Сортировка массива структуры

223
17 апреля 2018, 04:19

У меня есть структура

struct AirData {
    string marka_LA;
    string bortovoyNomer;
    int nomerReica;
    char vremayPosadki[6];
};

Так же текстовый файл из которого я запалняю эту структуру , который имеет вид:

марка  б.номер номер рейса время посадки 
 ТУ-154 Б-373   1763         23:35
 ВВ-213 В-132   393          23:38
 ВВ-123 в-213   3422         -09:32 
 Дд-231 ы-123   2321         -12:23
 Rw-123 as-12   2321         32:23

функция сортировки :

void swap_base(AirData &t1, AirData &t2) {   // функция для сотировки
    AirData tmp;
    tmp = t2;
    t2 = t1;
    t1 = tmp;
}



int main() {
    int N = 0; // количество строк
    string line;
    fstream file;
    file.open(fileName);
    // считываем кол-во строк
    if (file.is_open()){
        while (getline(file, line)) {
            N++;
        }
    }
    file.close();
    AirData base[N]; // Массив структуры данных
    file.open(fileName);
    if (file.is_open()){
        while (!file.eof()) {
            getline(file, line, ch);
            for (int j = 0; j < N; j++){
                for (int i = 0; i < 4; i++){
                    if (i == 0) {
                        file >> base[j].marka_LA;
                    }
                    if (i == 1) {
                        file >> base[j].bortovoyNomer;
                    }
                    if (i == 2) {
                        file >> base[j].nomerReica;
                    }
                    if (i == 3) {
                        file >> base[j].vremayPosadki;
                    }
                }
            }
        }

я заполняю массив струтуры, а дальше мне нужно отсортировать и вывести на экран по такому правилу: если время посадки >= 0, то сортировать по этому времени, если же < 0 , то сортировать по номеру рейса. не получается правильно оформить обработку

for (int i = 0; i < N; i++) {
    for(int j = i + 1; j < N; j++) {
        for(int v = 0; v < 6; v++){
            if (base[i].vremayPosadki[v] >= base[j].vremayPosadki[v])
                swap_base(base[i], base[j]);
        }
    }
}

// Если самолет в воздухе ( время меньше 0)
for (int k = 0; k < N; k++){
    if (base[k].vremayPosadki[0] == '-'){ // если время <0 то производим сортиоровку по номеру рейса хорошо)
        for (int i = k; i < N; i++) {
            for(int j = i + 1; j < N; j++) {
                if (base[i].nomerReica > base[j].nomerReica)
                    swap_base(base[i], base[j]);
            }
        }
    }
}
    for( int i=0; i< N;i++) {
        cout <<"marka_LA: "<< base[i].marka_LA <<" bortovoyNomer: "<<base[i].bortovoyNomer<<" nomerReica: "<<base[i].nomerReica<<" vremayPosadki: "<<base[i].vremayPosadki<<endl;
    }
}
Answer 1

Если вы не против, напишу с оптимизацией вашего кода:

struct AirData {
    string marka_LA;
    string bortovoyNomer;
    int nomerReica;
    int vremayPosadki[2];    // использовать время в виде чисел удобней
};

также можно время посадки хранить в обьекте std::pair<int> (23:35 можно считывать как 23 и 35) Для того, чтобы упростить код, уменьшить количество циклов и повторений выражений, сначала определим оператор ввода для вашей структуры:

istream& operator >>(istream& is, AirData& air)
{
    is >> air.marka_LA >> air.bortovoyNomer >> air.nomerReica >> air.vremayPosadki[0];
    is.ignore();                     // пропускаем символ ':'
    is >> air.vremayPosadki[1];      // считываем минуты
    return is;
}

Теперь определим компараторы:

bool cmpToFlight(const AirData &a1, const AirData &a2)
{
    return a1.nomerReica < a2.nomerReica;
}
bool cmpToTime(const AirData& a1, const AirData& a2)
{
    if(a1.vremayPosadki[0] == a2.vremayPosadki[0])
        return a1.vremayPosadki[1] < a2.vremayPosadki[1];
    return a1.vremayPosadki[0] < a2.vremayPosadki[0];
}

Теперь можно написать простенький код:

int main()
{ 
    // здесь ваш код, где вы определили количество строк в файле  
    //так как на первой строчке у вас  ярлыки, а не рейсы, прочтем ее 
    // как отдельную строку, а для рейсов будет на одну единицу меньше строк
    AirData base[N - 1];
    string s;
    getline(file, s);
    // благодаря написаноому нами оператору, легко введем обьекты структуры
    for (int i = 0; i < N - 1; ++i)
        file >> base[i];
    std::sort(base, &base[N], cmpToTime);
   // после этой сортировки, обьекты с полем отрицательной времени, будут 
   первыми  
   //найдем где конец таких и отсортируем по первому компаратору 
    int k = 0;
    while (base[k].vremayPosadki[0] < 0) ++k;   
    std::sort(base, &base[k], cmpToFlight);
    // проверим результат 
    cout << s << endl;
    for (int i = 0; i < N - 1; ++i)
        cout << base[i].marka_LA <<' ' << base[i].bortovoyNomer <<' '
             << base[i].nomerReica <<' ' << base[i].vremayPosadki[0] <<':'
             << base[i].vremayPosadki[1] << endl;
    return 0;
}

Не так уж трудно, когда логически раставляешь шаги. Конечно всегда можно написать и получше, но главное не размазать код разной ерундой... Желаю удачи!

READ ALSO
Подробный принцип работы hide VNC (hVNC)

Подробный принцип работы hide VNC (hVNC)

Кто нибудь знает как работает hVNC? Интересует именно создание параллельной сессии на пк которым нужно управлятьОчень удобно было бы работать...

305
Перехват функций под windows

Перехват функций под windows

Доброго вечера! Делал перехват вам по статье http://rsdnorg/article/baseserv/IntercetionAPI

169
Как искать критические секции в сложном и запутанном проекте?

Как искать критические секции в сложном и запутанном проекте?

Пишу многопоточное высоконагруженное клиент-серверное приложение на С++В приложении чётко определены четыре основных потока и так-же во время...

211