Сортировка массива структур C++

176
13 января 2020, 09:40

Есть массив строк:

char towns[][str] = { "Юрюпирийс 4000   Москва",
                "Москва    500    Питер ",
                "Мурманск  900    Луга  ",
                "Питер     2300   Москва"};

Я разделяю его в массив структур:

Airport_Pass s1[4];
for (int i = 0; i < 4; i++) {
    strncpy(s1[i].Departur, towns[i], DepartureLen);
    s1[i].Departur[DepartureLen] = '\0';
    char dop[80];
    strncpy(dop, towns[i] + DepartureLen, DistanceLen);
    s1[i].Distance = atoi(dop);
    strncpy(s1[i].Destination, towns[i] + DestinationStart, DestinationLen);
    s1[i].Destination[DestinationLen] = '\0';
    cout << " [" << s1[i].Departur << "] " << s1[i].Distance << " [" << s1[i].Destination << "]" <<endl;
}

Нужно спросить у пользователя по какому полю сортировать массив структур и вывести отсортированные структуры.Не могу понять как именно сделать сортировку по определённому полю.Нужно использовать одну функцию,а вот как это сделать - не знаю.По одному полю могу отсортировать,а по вбранному полю - нет

Полный код:

#include <iostream>
using namespace std;
const int DepartureLen = 9;
const int DistanceLen = 7;
const int DestinationLen = 9;
const int DistanceStart = DepartureLen;
const int DestinationStart = DistanceLen + DistanceStart;
const int str = DestinationStart + DistanceStart + 1;
struct Airport_Pass {
    int Distance;
    char Departur[DepartureLen + 1];
    char Destination[DestinationLen + 1];
};
int main() {
    setlocale(LC_CTYPE, "rus");
    Airport_Pass s1[4];
    char towns[][str] = { "Юрюпирийс 4000   Москва",
                          "Москва    500    Питер ",
                          "Мурманск  900    Луга  ",
                          "Питер     2300   Москва"
    };

for (int i = 0; i < 4; i++) {
    strncpy(s1[i].Departur, towns[i], DepartureLen);
    s1[i].Departur[DepartureLen] = '\0';
    char dop[80];
    strncpy(dop, towns[i] + DepartureLen, DistanceLen);
    s1[i].Distance = atoi(dop);
    strncpy(s1[i].Destination, towns[i] + DestinationStart, DestinationLen);
    s1[i].Destination[DestinationLen] = '\0';
    cout << " [" << s1[i].Departur << "] " << s1[i].Distance << " [" << s1[i].Destination << "]" <<endl;
}
system("pause");
}
Answer 1

Предлагаю такой вариант:

#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int DepartureLen = 9;
const int DistanceLen = 7;
const int DestinationLen = 9;
const int DistanceStart = DepartureLen;
const int DestinationStart = DistanceLen + DistanceStart;
const int str = DestinationStart + DistanceStart + 1;
const int LEN = 4;
struct Airport_Pass {
    int Distance;
    wchar_t Departur[DepartureLen + 1];
    wchar_t Destination[DestinationLen + 1];
};
int main() {
    //setlocale(LC_CTYPE, "rus");
    Airport_Pass s1[LEN];
    wchar_t towns[LEN][100] = { 
        L"Urupirsp 4000   Moskva",
        L"Moskow   500    Piter ",
        L"Murmansk 900    Luga  ",
        L"Piter    2300   Moskva"
    };

    auto departureCmp = [](const Airport_Pass & a, const Airport_Pass & b){return wcsncmp(a.Departur, b.Departur, DepartureLen) < 0;};
    auto destCmp = [](const Airport_Pass & a, const Airport_Pass & b){return wcsncmp(a.Destination, b.Destination, DestinationLen) < 0;};
    auto distCmp = [](const Airport_Pass & a, const Airport_Pass & b){return a.Distance < b.Distance;};
    std::map<int, bool (*)(const Airport_Pass &, const Airport_Pass &)> mp {
        {1, departureCmp},
        {2, destCmp},
        {3, distCmp},
    };
    for (int i = 0; i < LEN; i++) {
        wcsncpy(s1[i].Departur, towns[i], DepartureLen);
        s1[i].Departur[DepartureLen] = '\0';
        wchar_t dop[80];
        wcsncpy(dop, towns[i] + DepartureLen, DistanceLen);
        s1[i].Distance = wcstol(dop, nullptr, 10);
        wcsncpy(s1[i].Destination, towns[i] + DestinationStart, DestinationLen);
        s1[i].Destination[DestinationLen] = '\0';
        wcout << L" [" << s1[i].Departur << L"] " << s1[i].Distance << L" [" << s1[i].Destination << L"]" <<endl;
    }
    wcout << L"\nChoose field:\n1 - Departure\n2 - Destination\n3 - Distance";
    int variant;
    cin >> variant; // Добавить проверку введенного варианта
    std::sort(s1, s1 + LEN, mp[variant]);
    wcout << L"\nSorted:\n";
    for (int i = 0; i < LEN; i++) {
        wcout << L" [" << s1[i].Departur << L"] " << s1[i].Distance << L" [" << s1[i].Destination << L"]" <<endl;
    }
    system("pause");
}

Здесь строки заменены на длинные.

READ ALSO
Как ввести дробь через cin?

Как ввести дробь через cin?

С помощь scanf я могу ввести дробь таким образом:

167
Перегрузка макроса по числу параметров

Перегрузка макроса по числу параметров

Я хочу написать макрос FOO, так чтобы FOO(x) и FOO(x, y) делали разные вещиКак это сделать?

148
Не работает часть программы &ldquo;банкомат&rdquo; [закрыт]

Не работает часть программы “банкомат” [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»

179