Форум программистов, компьютерный форум CyberForum.ru

Сортировка массива структур (запутался я) - C++

Восстановить пароль Регистрация
 
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
11.02.2013, 14:53     Сортировка массива структур (запутался я) #1
Доброго времени!

собственно сразу обращение за помощью.

есть структура и массив таких структур:
C++
1
2
3
4
5
6
7
8
9
10
11
    struct iDiscipline{
        char name[10];
        int num_course;
        int num_term;
        int am_lec;
        int am_pr;
        int am_lab;
        int am_one;
        int am_ALL;
        char form[1]; //e-exam || t-test
    }disciplines[3];
...там дальше куча функций...

и вот есть сортировка(сортировка ли? ):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//вывод c сортировкой: имя(А-Я), семестр(1-12)
    //сперва сама сортировка методом пузырька
    for (int i=0; i<3; i++){
        iDiscipline buffer;//создаем структуру нашего типа, где будет временно храниться 1 запись из массива
        //сорт. по семестру
        for (int k=i+1; k<2; k++){
            if (disciplines[i].num_term>disciplines[k].num_term){
                //копируем в буфер
                for(int j=0; j<10; j++) buffer.name[j]=disciplines[i].name[j];//посимвольное копирование
                buffer.num_course=disciplines[i].num_course;
                buffer.num_term=disciplines[i].num_term;
                buffer.am_lec=disciplines[i].am_lec;
                buffer.am_pr=disciplines[i].am_pr;
                buffer.am_lab=disciplines[i].am_lab;
                buffer.am_one=disciplines[i].am_one;
                buffer.am_ALL=disciplines[i].am_ALL;
                buffer.form[0]=disciplines[i].form[0];
                //на скопированное место вставляем нов.стр-ру
                for(int j=0; j<10; j++) disciplines[i].name[j]=disciplines[k].name[j];
                disciplines[i].num_course=disciplines[k].num_course;
                disciplines[i].num_term=disciplines[k].num_term;
                disciplines[i].am_lec=disciplines[k].am_lec;
                disciplines[i].am_pr=disciplines[k].am_pr;
                disciplines[i].am_lab=disciplines[k].am_lab;
                disciplines[i].am_one=disciplines[k].am_one;
                disciplines[i].am_ALL=disciplines[k].am_ALL;
                disciplines[i].form[0]=disciplines[k].form[0];
                //на место нов.стр-ры вставляем из буфера
                for(int j=0; j<10; j++) disciplines[k].name[j]=buffer.name[j];
                disciplines[k].num_course=buffer.num_course;
                disciplines[k].num_term=buffer.num_term;
                disciplines[k].am_lec=buffer.am_lec;
                disciplines[k].am_pr=buffer.am_pr;
                disciplines[k].am_lab=buffer.am_lab;
                disciplines[k].am_one=buffer.am_one;
                disciplines[k].am_ALL=buffer.am_ALL;
                disciplines[k].form[0]=buffer.form[0];
            };
        };
    };
    //сортируем по названию
    for (int i=0; i<3; i++){
        iDiscipline buffer;
        for (int k=i+1; k<2; k++){
            if (strcmp(disciplines[i].name,disciplines[k].name)>0){
                //копируем в буфер
                for(int j=0; j<10; j++) buffer.name[j]=disciplines[i].name[j];//посимвольное копирование
                buffer.num_course=disciplines[i].num_course;
                buffer.num_term=disciplines[i].num_term;
                buffer.am_lec=disciplines[i].am_lec;
                buffer.am_pr=disciplines[i].am_pr;
                buffer.am_lab=disciplines[i].am_lab;
                buffer.am_one=disciplines[i].am_one;
                buffer.am_ALL=disciplines[i].am_ALL;
                buffer.form[0]=disciplines[i].form[0];
                //на скопированное место вставляем нов.стр-ру
                for(int j=0; j<10; j++) disciplines[i].name[j]=disciplines[k].name[j];
                disciplines[i].num_course=disciplines[k].num_course;
                disciplines[i].num_term=disciplines[k].num_term;
                disciplines[i].am_lec=disciplines[k].am_lec;
                disciplines[i].am_pr=disciplines[k].am_pr;
                disciplines[i].am_lab=disciplines[k].am_lab;
                disciplines[i].am_one=disciplines[k].am_one;
                disciplines[i].am_ALL=disciplines[k].am_ALL;
                disciplines[i].form[0]=disciplines[k].form[0];
                //на место нов.стр-ры вставляем из буфера
                for(int j=0; j<10; j++) disciplines[k].name[j]=buffer.name[j];
                disciplines[k].num_course=buffer.num_course;
                disciplines[k].num_term=buffer.num_term;
                disciplines[k].am_lec=buffer.am_lec;
                disciplines[k].am_pr=buffer.am_pr;
                disciplines[k].am_lab=buffer.am_lab;
                disciplines[k].am_one=buffer.am_one;
                disciplines[k].am_ALL=buffer.am_ALL;
                disciplines[k].form[0]=buffer.form[0];
            };
        };
    };
1е что меня смущает, это размер кода!! можно ли как нибудь упростить?
2е....сортировка как то не так работает..А!да!..нужно чеб первым делом сортировалась по названию, вторым - по семестру (поле - num_term).

воот...голова ваще не соображает..не сплю 2е сутки...

ЗЫ если надо, ввод и вывод записей:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
for (int i=0; i<3; i++) {
        cout<<i+1<<"я дисциплина:"<<endl;
        cout<<"\tНазвание дисциплины - "; scanf("%s",disciplines[i].name);
        cout<<"\tНомер курса - "; cin>>disciplines[i].num_course;
        //проверка адекватности ввода номера курса
        while (disciplines[i].num_course<1 || disciplines[i].num_course>6){
            cout<<"Введено неверное значение! Пожалуйста, поворите ввод - ";
            cin>>disciplines[i].num_course;
        }
        cout<<"\tНомер семестра - "; cin>>disciplines[i].num_term;
        //проверка адекватности ввода номера курса
        while (disciplines[i].num_term<1 || disciplines[i].num_term>12){
            cout<<"Введено неверное значение! Пожалуйста, поворите ввод - ";
            cin>>disciplines[i].num_term;
        }
        cout<<"\tКол-во часов лекций - "; cin>>disciplines[i].am_lec;
        cout<<"\tКол-во часов практик - "; cin>>disciplines[i].am_pr;
        cout<<"\tКол-во часов лабораторных - "; cin>>disciplines[i].am_lab;
        cout<<"\tКол-во часов сам. работ - "; cin>>disciplines[i].am_one;
        cout<<"\tКол-во часов ВСЕГО - "; cin>>disciplines[i].am_ALL;
        //проверяем адекватность поля ВСЕГО часов, путем сложения и сравнения
        while (disciplines[i].am_ALL != (disciplines[i].am_one+disciplines[i].am_lab+disciplines[i].am_pr+disciplines[i].am_lec)){
            cout<<"Введено неверное значение! Пожалуйста, поворите ввод - ";
            cin>>disciplines[i].am_ALL;
        }
        int choose;
        cout<<"\tФорма отчета:\n\t\t1.тест;\n\t\t2.экзамен\n\t\t-"; cin>>choose;
        //проверяем правильность ввода
        do {
            switch (choose){
            case 1:
                disciplines[i].form[0]='e';
                break;
            case 2:
                disciplines[i].form[0]='t';
                break;
            default:
                cout<<"Введено неверное значение! Пожалуйста, поворите ввод\n\t\t1.тест;\n\t\t2.экзамен\n\t\t-"; cin>>choose;
            };
        }
        while (choose<1 || choose>2);
    };
C++
1
2
3
4
5
6
7
8
9
cout<<"Наименование:    "; for (int i=0; i<3; i++) printf("|%s|",disciplines[i].name);
    cout<<endl<<"Номер курса;     "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].num_course<<" |";
    cout<<endl<<"Номер семестра:  "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].num_term<<" |";
    cout<<endl<<"Лекции (ч):      "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].am_lec<<" |";
    cout<<endl<<"Практика (ч):    "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].am_pr<<" |";
    cout<<endl<<"Лабы (ч):        "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].am_lab<<" |";
    cout<<endl<<"Сам.раб. (ч):    "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].am_one<<" |";
    cout<<endl<<"ВСЕГО (ч):       "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].am_ALL<<" |";
    cout<<endl<<"Форма отчета:    "; for (int i=0; i<3; i++) cout<<"| "<<disciplines[i].form[0]<<" |";
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2013, 14:53     Сортировка массива структур (запутался я)
Посмотрите здесь:

C++ Сортировка массива структур
C++ Сортировка массива структур
Сортировка массива структур C++
C++ Сортировка массива структур
Сортировка массива структур C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Байт
 Аватар для Байт
13940 / 8771 / 1219
Регистрация: 24.12.2010
Сообщений: 15,872
11.02.2013, 15:09     Сортировка массива структур (запутался я) #2
C
1
2
buffer.num_course=disciplines[i];
....
Цитата Сообщение от zerO2hacK Посмотреть сообщение
е что меня смущает, это размер кода!! можно ли как нибудь упростить?
Добавлено через 1 минуту
Это в место 9 строчек кода...
А почему не пользуешься qsort ?
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
11.02.2013, 16:11  [ТС]     Сортировка массива структур (запутался я) #3
Цитата Сообщение от Байт Посмотреть сообщение
buffer.num_course=disciplines[i];
эммм...что то я не понял строчки....получается же че в переменную int мы записываем структуру? оО


Цитата Сообщение от Байт Посмотреть сообщение
А почему не пользуешься qsort ?
такой функции не знал, щас загуглил и как впихнуть ее в мой код не понял...
Байт
 Аватар для Байт
13940 / 8771 / 1219
Регистрация: 24.12.2010
Сообщений: 15,872
11.02.2013, 16:52     Сортировка массива структур (запутался я) #4
Цитата Сообщение от zerO2hacK Посмотреть сообщение
эммм...что то я не понял строчки....получается же че в переменную int мы записываем структуру?
Извиняюсь, ошибочка вышла конечно
C
1
buffer=disciplines[i];
Т.е. не надо поэлементно, можно одним оператором всю структуру переписать.

Цитата Сообщение от zerO2hacK Посмотреть сообщение
как впихнуть ее в мой код не понял.
C
1
 qsort(diskiplines, 3, siziof(iDiscipline), fcmp);
Предварительно описываешь функцию сравнения fcmp(iDiscipline *p1, iDiscipline *p2)

Добавлено через 3 минуты
Что-нибудь типа
C
1
2
3
4
5
6
int fcmp(iDiscipline *p1, iDiscipline *p2)
{
if (p1->num_term>p2->num_term) return 1;
else if (p1->num_term>p2->num_term) return -1;
else eturn 0;
}
Посмотри примеры
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
11.02.2013, 20:27  [ТС]     Сортировка массива структур (запутался я) #5
Цитата Сообщение от Байт Посмотреть сообщение
Т.е. не надо поэлементно, можно одним оператором всю структуру переписать.
оу...и правда....затупил

а qsort щас поизучаю.

Спасибо тебе!

Добавлено через 1 час 9 минут
почему не получается использовать тернарную операцию таким образом?
return p1->num_name>p2->num_name ? 1 : (p1->num_name<p2->num_name : -1 : 0);
вроде все често, если ложь, то вернуть значение из скобок...ругается тут ^ на ":" (в выделенном месте)
Wolkodav
 Аватар для Wolkodav
599 / 452 / 32
Регистрация: 18.09.2012
Сообщений: 1,685
11.02.2013, 20:33     Сортировка массива структур (запутался я) #6
эммм, вам тут надо еще знак вопроса, с чем сравниваете, а потом -1.
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
11.02.2013, 20:36  [ТС]     Сортировка массива структур (запутался я) #7
теперь по qsort:

описал функцию сравнения
C++
1
2
3
4
5
int filter_name(iDiscipline *p1, iDiscipline *p2){
    if (p1->num_name>p2->num_name) return 1;
    else if (p1->num_name<p2->num_name) return -1;
    else return 0;
}
а вот вызов qsort:
C++
1
qsort(disciplines, 3, sizeof(iDiscipline), filter_term);
ругается и в filter_name (скрин 1) и в qsort (скрин 2)
Миниатюры
Сортировка массива структур (запутался я)   Сортировка массива структур (запутался я)  
zerO2hacK
1 / 1 / 0
Регистрация: 06.03.2012
Сообщений: 72
11.02.2013, 21:39  [ТС]     Сортировка массива структур (запутался я) #8
Цитата Сообщение от Wolkodav Посмотреть сообщение
эммм, вам тут надо еще знак вопроса, с чем сравниваете, а потом -1.
мдее) спасибо что заметил

Добавлено через 49 минут
я всё, победил, без qsort, а простым методом пузыря
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for (int i=0; i<3; i++){
        //сорт. по семестру
        for (int k=i+1; k<3; k++){
            //создаем структуру нашего типа, где будет временно храниться 1 запись из массива
            iDiscipline buffer;
            if (disciplines[i].num_term>disciplines[k].num_term){
                //копируем в буфер
                buffer=disciplines[i];
                //на скопированное место вставляем нов.стр-ру
                disciplines[i]=disciplines[k];
                //на место нов.стр-ры вставляем из буфера
                disciplines[k]=buffer;
            };
            if (strcmp(disciplines[i].name,disciplines[k].name)>0){
                //копируем в буфер
                buffer=disciplines[i];
                //на скопированное место вставляем нов.стр-ру
                disciplines[i]=disciplines[k];
                //на место нов.стр-ры вставляем из буфера
                disciplines[k]=buffer;
            };
        };
    };
все дело было в том, что сортировка выполнялась не до конца - во втором цикле for (int k=i+1; k<3; k++), вместо k<3 стояло k<2....я че то думал, что иначе за стек будет вылезать, а нет, все нормуль

Добавлено через 12 минут
но вопрос про qsort остается в силе. хочу и этот способ добить!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.02.2013, 23:03     Сортировка массива структур (запутался я)
Еще ссылки по теме:

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

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Байт
 Аватар для Байт
13940 / 8771 / 1219
Регистрация: 24.12.2010
Сообщений: 15,872
11.02.2013, 23:03     Сортировка массива структур (запутался я) #9
Цитата Сообщение от zerO2hacK Посмотреть сообщение
почему не получается использовать тернарную операцию таким образом?
return p1->num_name>p2->num_name ? 1 : (p1->num_name<p2->num_name : -1 : 0);
Будь попроще. Если сложный вложенный оператор не работает - разбей его на простые.

Добавлено через 4 минуты
Цитата Сообщение от zerO2hacK Посмотреть сообщение
но вопрос про qsort остается в силе. хочу и этот способ добить!
Удачи!
Пригодится, 100 пудов!
Не описываю подробностей, потому как разные компиляторы по-разному строго обрабатывают ссылку на функцию (функтор) fcmp. Ищи примеры в своем, если они есть. В противном случае, метода тыка еще никто не отменял

Добавлено через 35 минут
zerO2hacK, По твоему скрину понял, что параметры filter_name надо писать как const void *p1.., а уже внутри ее приводить к (iDiscipline *)p1 ...
Yandex
Объявления
11.02.2013, 23:03     Сортировка массива структур (запутался я)
Ответ Создать тему
Опции темы

Текущее время: 01:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru