Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 27.02.2022
Сообщений: 4

Сортировка массива структур сразу по нескольким полям

27.02.2022, 18:09. Показов 1276. Ответов 3

Студворк — интернет-сервис помощи студентам
Здравствуйте. По заданию нужно отсортировать массив на 100.000 структур по трём признакам(одновременно): класс -> фамилия -> имя. Сделала сортировку пузырьком. Работает, но очень много времени требует.. Подскажите, пожалуйста, как реализовать более оптимально?
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <ctime> 
#include <Windows.h> 
 
int randInteger(int A, int B)
{
    return rand() % (B - A + 1) + A; 
}
 
struct Student
{
    char* name;     //имя
    char* surname;  //фамилия
    int age;        //возраст
    int grade;      //номер класса
};
 
void createStr(char* name, int k)
{
    char* nameq = new char[k + 1]{ '\n' };
    if (randInteger(0, 32) == 0) //должна быть равная вероятность выпадения в том числе и буквы Ё
    {
        nameq[0] = -88;
    }
    else
    {
        nameq[0] = randInteger(-64, -33);
    }
    for (int i = 1; i < k; i++)
    {
        /*srand(time(NULL));*/
        if (randInteger(0, 32) == 0) //должна быть равная вероятность выпадения в том числе и буквы ё
        {
            nameq[i] = -72;
        }
        else
        {
            nameq[i] = randInteger(-32, -1);
        }
    }
    strcpy_s(name, k + 1, nameq);
}
 
void createClass(Student* Class9A)
{
    int k{ 0 };
    for (int i = 0; i < 100000; i++)
    {
        Class9A[i].grade = randInteger(1, 11);
 
        Class9A[i].age = Class9A[i].grade + 6 + randInteger(-1, 1);
 
        k = randInteger(2, 15);
        Class9A[i].name = new char[k + 1]{'\0'};
        createStr(Class9A[i].name, k);
 
        k = randInteger(2, 15);
        Class9A[i].surname = new char[k + 1]{ '\0' };
        createStr(Class9A[i].surname, k);
    }
}
 
void sort(Student* Class9A)
{
    Student temp;
    for (int i = 0; i < 100000 - 1; i++)
    {
        bool flag = false;
        for (int j = 0; j < 100000 - 1 - i; j++)
        {
            if (Class9A[j].grade > Class9A[j + 1].grade)
            {
                temp = Class9A[j];
                Class9A[j]= Class9A[j + 1];
                Class9A[j + 1] = temp;
                flag = true;
            }
            else if (Class9A[j].grade == Class9A[j + 1].grade)
            {
                if (strcmp(Class9A[j].surname, Class9A[j + 1].surname) == 1)
                {
                    temp = Class9A[j];
                    Class9A[j] = Class9A[j + 1];
                    Class9A[j + 1] = temp;
                    flag = true;
                }
                else if (strcmp(Class9A[j].surname, Class9A[j + 1].surname) == 0)
                {
                    if (strcmp(Class9A[j].name, Class9A[j + 1].name) == 1)
                    {
                        temp = Class9A[j];
                        Class9A[j] = Class9A[j + 1];
                        Class9A[j + 1] = temp;
                        flag = true;
                    }
                }
            }
 
        }
        if (flag == false)
        {
            break;
        }
    }
    for (int i = 0; i < 100000; i++)
    {
        std::cout << Class9A[i].grade << '\t' << Class9A[i].surname << '\t' << Class9A[i].name << std::endl;
    }
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    srand(time(NULL));
 
        Student* Class9A = new Student[100000];
    createClass(Class9A); 
        sort(Class9A);
 
        for (int i = 0; i < 100000; i++)
    {
        delete Class9A[i].name;
        delete Class9A[i].surname;
    }
    delete[] Class9A; 
        return 0;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.02.2022, 18:09
Ответы с готовыми решениями:

Упорядочивание массива структур по нескольким полям
Есть программа,которая сортирует студентов по году рождения. #include &lt;conio.h&gt; #include &lt;iostream&gt; #include &lt;stdio.h&gt; ...

Сортировка массива структур по разным полям
Имеется массив студентов. Подскажите, пожалуйста, как сортировать их по полю &quot;курс&quot; и полю &quot;фамилия&quot; . #include...

Как проверить в валидаторе уникальность сразу по нескольким полям из БД
Добрый день! Есть база данных с полями: id, x, y, z Есть к примеру 3 записи: id 1, x = 1, y = 1, z = 1 id 2, x = 1, y = 2, z...

3
236 / 50 / 37
Регистрация: 24.01.2022
Сообщений: 137
27.02.2022, 18:32
Лучший ответ Сообщение было отмечено dbmlfdbvibm как решение

Решение

dbmlfdbvibm, попробуйте использовать функцию сортировки из стандартной библиотеки:

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
#include <cstring>
#include <algorithm>
 
void sort(Student* Class9A)
{
    std::sort(&Class9A[0], &Class9A[100000], [](const Student& lhs, const Student& rhs) {
        if (lhs.grade > rhs.grade) 
            return true;
        else if (lhs.grade == rhs.grade) {
            const int resSurname = std::strcmp(lhs.surname, rhs.surname);
            if (resSurname == 1) {
                return true;
            }
            else if (resSurname == 0) {
                if (std::strcmp(lhs.name, rhs.name) == 1) {
                    return true;
                }
            }
        }
        return false;
    });
    for (int i = 0; i < 100000; i++)
    {
        std::cout << Class9A[i].grade << '\t' << Class9A[i].surname << '\t' << Class9A[i].name << std::endl;
    }
}
В вашем решении, для ускорения "запоминайте" результат функции "strcmp":

C++
1
2
3
4
5
6
7
const int resSurname = strcmp(lhs.surname, rhs.surname);
if (resSurname == 1) {
    //...
}
else if (resSurname == 0) {
    //...
}
1
0 / 0 / 0
Регистрация: 27.02.2022
Сообщений: 4
27.02.2022, 18:39  [ТС]
Mushroomer, большое спасибо! Это то, что нужно. Не могли бы Вы ещё подсказать, как сделать так, чтобы сортировка шла по возрастанию?
0
236 / 50 / 37
Регистрация: 24.01.2022
Сообщений: 137
27.02.2022, 18:44
dbmlfdbvibm, например так, но с буквой 'Ё' беда:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//...
        if (lhs.grade < rhs.grade) 
            return true;
//...
            if (resSurname == -1) {
                return true;
            }
            else if (resSurname == 0) {
                if (std::strcmp(lhs.name, rhs.name) == -1) {
                    return true;
                }
            }
//...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.02.2022, 18:44
Помогаю со студенческими работами здесь

Как вносить данные в объект сразу по нескольким полям за один раз
Всем привет, допустим, хочу вносить данные в объект в консоли вот так Имя...(курсор здесь и здесь вношу) Фамилия...(потом могу ...

Сортировка по нескольким полям
Есть таблица с полями id, shopID, description, active, vip Нужно вывести отсортированные 9 записей по id, но чтобы записи с vip=1 были...

Сортировка по нескольким полям
В бaзe данныx хранитcя N зaписей видa (Name, a1, a2, . . . , ak) – во всeх зaписях oдинаковое чиcло пaраметров. Нa вхoд зaдачи пoдаётся...

Сортировка по нескольким полям
Имеется массив учеников. Написать программу, которая вводит ФИО,пол,возраст,класс каждого из этих учеников и печатает...

Сортировка по нескольким полям
Добрый день.Есть следующая многострадальная задача: Построить три класса (базовый и 2 потомка), описывающих некоторых работников с...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Ниже машинный перевод статьи The Thinkpad X220 Tablet is the best budget school laptop period . Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы,. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru