С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
1

Сортировка массива структур по одному полю

17.01.2017, 15:40. Показов 3713. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую.
Задача: отсортировать по возрастанию структуру по одному полю.
Вчера поднимал тему: Сортировка массива структур по одному полю
Здесь же новый косяк, не понимаю, как вытащить значения под сортировку в функции Sort (закомментированные строки).
Прошу помощи.

Структуры:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Student {
    char name[20];
    char sex[2];
    int age;
    int semester;
    char estimate[11];
};
 
struct Group {
    Student** pS;
    int ActSize;
    int capacity;
};
Main:
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
int main()
{
    Group group;
    group.capacity = 2;
 
    group.pS = new Student *[group.capacity];
    group.ActSize = 0;
 
    for (int i = 0; i < group.capacity; i++)
    {
        group.pS[i] = nullptr;
    }
 
    enum ChoiceFunc { form = 1, print, exp, imp, sort, exit };
    for (;;)
    {
        int res = Menu();
        switch (res)
        {
        case 1: FormGroup(&group);
            break;
        case 2: Print(&group);
            break;
        case 3: ExportGroup(&group);
            break;
        case 4: ImportGroup(&group);
            break;
        case 5: Sort(&group, CmpAge, SwapAge);
            break;  
        case 6: return 0; 
 
        }
        stop
    }
    return 0;
}
Реализация:
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
bool CmpAge(Student* p1, Student* p2)
{
 
    return ((p1->age) > (p2->age));
}
 
void SwapAge(void* p1, void* p2)
{
    Student* ptmp1 = static_cast<Student*>(p1);
    Student* ptmp2 = static_cast<Student*>(p2);
 
    Student buf = *ptmp1;
    *ptmp1 = *ptmp2;
    *ptmp2 = buf;
}
 
 void Sort(struct Group* pk, bool(*Cmp)(Student*,Student*), void(*Swap)(void*,void*))
 
{
    for (int i = 0; i < pk->ActSize; i++)
    {
        for (int j = pk->ActSize-1; j >=i; j--)
        {
            //Student* current = pk[j].pS;
            //Student* next = pk[j + 1].pS;
 
            if ((*Cmp)(current, next) == true)
            {
                (*Swap)(current, next);
            }
        }
    }
    printf("\n\nSorted group:\n\n");
 
    for (int i = 1; i < pk->ActSize; i++)
    {
        printf("Name: %s\n  Sex : %s\n Age : %d\n Semester %d\n Estimates %s\n",
            pk->pS[i]->name, pk->pS[i]->sex, pk->pS[i]->age, pk->pS[i]->semester, pk->pS[i]->estimate);
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2017, 15:40
Ответы с готовыми решениями:

Сортировка массива структур по одному полю
Приветствую. Есть задача, практически аналогичная моей:...

Сортировка массива(вектора)структур по одному полю
Код:#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;vector&gt; #include &lt;algorithm&gt; struct...

Сортировка массива структур по полю
Дана структура: struct elecHelp1 { char fio, name, sname, nameElection, constituensy; double...

Сортировка массива структур по заданному полю
Здравствуйте. Нужна помощь в сортировке. Вот само задание: Составить таблицу, содержащую...

14
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 15:46 2
C++
1
2
3
4
if ((*Cmp)(&pk[j], &pk[j+1]))
{
    (*Swap)(&pk[j], &pk[j+1]));
}
0
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 15:53  [ТС] 3
nonedark2008,
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
void Sort(char* pcFirst, int nNumber, int size,
    void(*Swap)(void*, void*), int(*Compare)(void*, void*))
{
    int i;
    for (i = 1; i<nNumber; i++)
        for (int j = nNumber - 1; j >= i; j--)
        {
            char* pCurrent = pcFirst + j*size; //!!!
            char* pPrevious = pcFirst + (j - 1)*size; //!!!
            if ((*Compare)(pPrevious, pCurrent) > 0)//требуется
                                                    //переставить
                (*Swap)(pPrevious, pCurrent);
        }
}
 
 
 
void SwapInt(void* p1, void* p2)
{
    int* ptmp1 = static_cast<int*>(p1);
    int* ptmp2 = static_cast<int*>(p2);
 
    int buf = *ptmp1;
    *ptmp1 = *ptmp2;
    *ptmp2 = buf;
 
    return;
}
 
int CmpInt(void* p1, void* p2)
{
    int* pp1 = static_cast<int*>(p1);
    int* pp2 = static_cast<int*>(p2);
 
    int nResult = *pp2 - *pp1;
 
    return nResult;
    stop
}
Писалось на основе этого примера.
Отмеченные !!! строки собственно и не понимаю как в своем случае реализовать.

Добавлено через 3 минуты
MrGluck, так несовмещение ж типов будет
0
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 15:53 4
Цитата Сообщение от GetShuk Посмотреть сообщение
Student** pS;
А зачем вам указатель на указатель?
0
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 15:54  [ТС] 5
MrGluck, по заданию так.
0
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 15:54 6
Я сначала подумал, что вы как белый человек передаёте в Sort массив из Student.

Добавлено через 17 секунд
Цитата Сообщение от GetShuk Посмотреть сообщение
MrGluck, по заданию так.
И на что он должен указывать?
0
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 15:56  [ТС] 7
MrGluck, это-то и надо. А понимания нет.

Добавлено через 1 минуту
MrGluck, на элементы массива структур Group, т.е. на Student[0], Student[1] итд
0
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
17.01.2017, 16:04 8
Кликните здесь для просмотра всего текста
del
1
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 16:09  [ТС] 9
JIawliet,
Цитата Сообщение от JIawliet Посмотреть сообщение
Student* current = pk->pS[i]
фурычит, спасибо. Если еще и объясните, почему так, а не иначе, цены вам не будет
0
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 16:15 10
Лучший ответ Сообщение было отмечено GetShuk как решение

Решение

У вас ещё и функция сортировки была неверно написана.
Вот, ваш пример, более менее причёсанный. Хотя я бы использовал классы с методами и ссылки вместо указателей, но дело хозяйское.
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
#include <cstring>
#include <iostream>
 
struct Student
{
    char name[20];
    int age;
    // ...
};
 
bool CmpAge(Student* p1, Student* p2)
{
    return (p1->age) > (p2->age);
}
 
void Swap(Student* p1, Student* p2)
{
    Student buf = *p1;
    *p1 = *p2;
    *p2 = buf;
}
 
struct Group
{
    Student* pS;
    int ActSize;
    // ...
};
 
void Sort(Group *pk, bool(*Cmp)(Student*, Student*))
{
    for (int i = 0; i < pk->ActSize; i++)
    {
        for (int j = pk->ActSize-1; j > i; j--)
        {
            if ((*Cmp)(&pk->pS[j-1], &pk->pS[j]))
            {
                Swap(&pk->pS[j-1], &pk->pS[j]);
            }
        }
    }
}
 
void Print(Group *pk)
{
    for (int i = 0; i < pk->ActSize; i++)
        std::cout << pk->pS[i].name << " " << pk->pS[i].age << std::endl;
}
 
int main()
{
    const int N = 2;
    Group g;
    g.pS = new Student[N];
    g.ActSize = N;
    strcpy(g.pS[0].name, "Eniki");
    g.pS[0].age = 42;
    strcpy(g.pS[1].name, "beniki");
    g.pS[1].age = 2;
 
    Print(&g);
    Sort(&g, CmpAge);
    Print(&g);
 
    delete[] g.pS;
}
Добавлено через 2 минуты
Цитата Сообщение от GetShuk Посмотреть сообщение
Если еще и объясните, почему так, а не иначе
Для начала мы разыменовываем указатель pk и обращаемся к полю структуры pS (это оператор ->). Далее, учитывая, что pS указывает на массив, используем оператор доступа по индексу. То есть мы работаем с массивом pk->pS как если бы это был просто массив Student. И не важно, что это поле структуры.

Добавлено через 30 секунд
Цитата Сообщение от GetShuk Посмотреть сообщение
на элементы массива структур Group, т.е. на Student[0], Student[1] итд
Для этого достаточно одномерного массива. Я потому и спросил.
1
90 / 88 / 33
Регистрация: 20.07.2016
Сообщений: 403
17.01.2017, 16:17 11
Цитата Сообщение от GetShuk Посмотреть сообщение
фурычит, спасибо. Если еще и объясните, почему так, а не иначе, цены вам не будет
вы поторопились) я сомневаюсь, что тот кусок кода, который я оставил будет работать корректно)

Цитата Сообщение от GetShuk Посмотреть сообщение
C++
1
Student* current = pk->pS[i]
pk - указатель на структуру, с помощью оператора стрелки получаем доступ к pS (указатель на указатель), а вот тут начинается веселье и тот код, который я оставил - неверный, поэтому я его и удалил... правильно ли я понял, что вы хотите отсортировать матрицу???? потому что pS это массив массивов.

Добавлено через 1 минуту
Цитата Сообщение от MrGluck Посмотреть сообщение
Хотя я бы использовал классы с методами и ссылки вместо указателей
С++ == std::sort + предикат
1
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 16:21 12
Цитата Сообщение от JIawliet Посмотреть сообщение
С++ ==
Если требуется своя функция сортировки, то компаратор std::function/параметр шаблона.
Но тут у ТС жёстко заданы сигнатуры некоторых функций, да и вообще "ничего нельзя".
То, что я привёл - подредактированный код ТС, практически С.
0
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 16:25  [ТС] 13
JIawliet, есть структура Group, содержащая в себе массив структур Student, и этих студентов надо отсортировать по одному из полей (возрасту, например). + пример работал корректно на 3х структурах в массиве структур Group.
MrGluck, классы еще не проходили. И заполнение структуры у меня идет через отдельную функцию:
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
void FormGroup(struct Group* pk)
{
    int val = 1;
    while (val == 1)
        {
            //перераспределение памяти, если необходимо
            if ((pk->ActSize) >= (pk->capacity))
            {
                pk -> capacity = +2;
                Student **tmp = new Student*[pk->capacity];
                for (int i = 0; i < pk->capacity; i++)
                {
                    tmp[i] = pk->pS[i];
                }
                delete[] pk -> pS;
                pk -> pS = tmp;
            }
 
            pk->pS[pk->ActSize] = new Student;
 
 
            printf("\nName: ");
            scanf("%19s", pk->pS[pk->ActSize]->name);
            fseek(stdin, SEEK_END, 0);
 
            printf("\nSex (m / f): ");
            scanf("%1s", pk->pS[pk->ActSize]->sex);
            
            do {
                printf("\nAge: ");
                scanf("%d", &(pk->pS[pk->ActSize]->age));
            } while (((pk->pS[pk->ActSize])->age < 17));
                
 
            do {
                printf("\nSemester: ");
                scanf("%d", &(pk->pS[pk->ActSize]->semester));
            } while (((pk->pS[pk->ActSize])->semester < 1));
 
            printf("\nPut estimates (no more 10): ");
            scanf("%10s", pk->pS[pk->ActSize]->estimate );
 
            pk->ActSize++;
 
            printf("\nDo you want input next student? yes(1) / no(0): ");
            scanf("%d", &val);
 
            if (val == 0)
            {
                break;
            }
        }
}
В этом случае как main строится?
C++
1
2
3
4
 strcpy(g.pS[0].name, "Eniki");
    g.pS[0].age = 42;
    strcpy(g.pS[1].name, "beniki");
    g.pS[1].age = 2;
Этот кусок не нужен, получается.
0
Форумчанин
Эксперт CЭксперт С++
8216 / 5046 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
17.01.2017, 16:28 14
Цитата Сообщение от GetShuk Посмотреть сообщение
классы еще не проходили.
как я и предполагал.
Цитата Сообщение от GetShuk Посмотреть сообщение
И заполнение структуры у меня идет через отдельную функцию:
Без разницы, в моём примере заполнение играет второстепенную роль. Мне лень вбивать каждый раз данные, поэтому я их заполнил явно в main.
Вас должны интересовать приведённые мною функции.
1
3 / 3 / 1
Регистрация: 06.07.2016
Сообщений: 73
17.01.2017, 16:31  [ТС] 15
MrGluck, их уже посмотрел, ошибки понял. Давно уже колупаюсь, поэтому справшиваю все.

Добавлено через 1 минуту
MrGluck, JIawliet, за разъяснения отдельное спасибо.
0
17.01.2017, 16:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2017, 16:31
Помогаю со студенческими работами здесь

Сортировка массива структур по полю lastname
имеется структура struct { char lastname, firstname; unsigned int math, inf, phys; }rat,...

Сортировка массива структур по полю date
Здравствуйте! Помогите пожалуйста реализовать сортировку массива структур по полю &quot;date&quot; (все...

Сортировка массива структур по определенному полю
Всем привет...со структурами проблемка возникла...затупил)Задание состоит в следующем: Ввести...

Сортировка массива структур по заданному полю
Задание под вариантом такое : Упорядочить список студентов по предмету физика, и вывести весь...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru