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

Сортировка, не изменяя структуру - C++

Восстановить пароль Регистрация
 
 
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 11:05     Сортировка, не изменяя структуру #1
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
130
131
#include <conio.h>
#include <string.h>
#include <stdio.h>
 
struct autopark{          //объявление структуры autopark
char brand[30];      //марка автобуса
char date[30];      //год выпуска автобуса
char number[10];          //маршрут автбуса
}a[30];   
int addition(int i);    //добавление данных
int delet(int d);       //удаление данных
void showing(int n);    //показ данных
void sort(int i);     //сортировка данных
 
int main()
{
int key,d=0;
while(1)
 {
 
printf("\nMenu");                 
printf("\n1.Add the data");
printf("\n2.Display all details");
printf("\n3.Deleting data");
printf("\n4.Sort the data");
printf("\n\nTo exit, press Esc \n\n");
key=getch(); 
 
if(key==27) break;
 
switch(key)      //Выбор действия
{ 
case 49: d=addition(d);break;
case 50: showing(d);break;
case 51: d=delet(d);break;
case 52: sort(d);break;
}
getch();
}
}
 
int addition(int i)     //функция для добавления данных
{
puts("Enter the brand of the bus: ");
scanf("%s",a[i].brand);
puts("Enter the year the bus");
scanf("%s",a[i].date);
puts("Enter the number of bus");
scanf("%s",a[i].number);
return i+1;
}
int delet(int n)      //функция для удаления данных
{
int i,d;
printf("\nEnter the number of write to remove: ");
scanf("%d",&d);
for (i=d-1;i<n-1;i++)
{
strcpy(a[i].brand,a[i+1].brand);
strcpy(a[i].date,a[i+1].date);
strcpy(a[i].number,a[i+1].number);
return n-1;
}
}
 
void showing(int n)    //функция показа данных
{
int i;
printf("\n_________________________________\n");
printf("|N |Brand     |Year      |Number|\n");
printf("_________________________________\n");
for (i=0;i<n;i++)
 {
printf("|%-2d|%-10s|%-10s|%-3s   |\n",i+1,a[i].brand,a[i].date,
a[i].number);
}
printf("_________________________________");
}
 
void sort(int i)    //функция сортировки данных
{
int n,temp,button;
printf("\nMenu");                 
printf("\n1.Brand");
printf("\n2.Date");
printf("\n3.Number");
printf("\n\nTo exit, press Esc \n\n");
button=getch(); 
 
if(button==29) break;
 
switch(button)      //Выбор действия
{ 
case 49: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[i].brand>a[j].brand)
                    {
                           temp=i;;
                           i=j;
                           j=temp;
                    }
            }
    };break;
case 50: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[i].date>a[j].date)
                    {
                           temp=i;;
                           i=j;
                           j=temp;
                    }
            }
    };break;
case 51: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[i].number>a[j].number)
                    {
                           temp=i;;
                           i=j;
                           j=temp;
                    }
            }
    };break;
}
}
Нужно, чтобы оно сортировало порядковый номер записи в структуре, но не получается. Не понимаю как это передать в функцию показа данных. И ещё не работает break в функции сортировки, когда if(button==29) break;
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2012, 11:05     Сортировка, не изменяя структуру
Посмотрите здесь:

C++ Структуру
C++ Циклическая программа (при нажатии клавиши повторяет операцию, изменяя данные)
C++ Составить новый массив, изменяя значения элементов в зависимости от того, отсортирована ли текущая строка
C++ функция изменяет старший байт числа на заданное значение не изменяя младший байт
C++ запись в файл, не изменяя размер самого файла
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Venzo
 Аватар для Venzo
125 / 123 / 4
Регистрация: 03.07.2011
Сообщений: 354
30.04.2012, 11:44     Сортировка, не изменяя структуру #2
break служит для прерывания цикла, а вам, вероятно, нужно использовать тут return; (для завершения функции ведь?)

C++
1
2
3
temp=i;;
i=j;
j=temp;
Вы меняете местами значение индексов, а не сами элементы. т.е если i=30, j=5, то после этих строк i=5, j=30.
попробуйте так
C++
1
2
3
4
autopark temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 11:46  [ТС]     Сортировка, не изменяя структуру #3
так в том и дело что элементы нужно оставить на своих местах
1 Икарус 1980 3
2 МАЗ 2002 1
Сортируем по маршруту и получаем:
2 Икарус 1980 3
1 МАЗ 2002 1
Вот так мне нужно, чтобы порядковый инлекс менялся
Venzo
 Аватар для Venzo
125 / 123 / 4
Регистрация: 03.07.2011
Сообщений: 354
30.04.2012, 11:53     Сортировка, не изменяя структуру #4
до сортировки
a[1] = /*икарус*/;
a[2] = /*маз*/;
после
a[2] = /*икарус*/;
a[1] = /*маз*/;
так чтоли? не понятно, что вы хотите сделать)
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 12:07  [ТС]     Сортировка, не изменяя структуру #5
да не, так вы поменяете их местами в струтуре, а по заданию так нельзя, нужно просто чтобы в таблице(которая в функции показа) поменялся порядковый номер, т.е к примеру было
1
2
3
4
а отсортировали по какому-нибудь критерию и стало
3
1
4
2
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
30.04.2012, 12:11     Сортировка, не изменяя структуру #6
Создавайте отдельный массив с порядком. Других вариантов нет.
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 12:23  [ТС]     Сортировка, не изменяя структуру #7
Цитата Сообщение от Toshkarik Посмотреть сообщение
Создавайте отдельный массив с порядком. Других вариантов нет.
а потом как упорядочить элементы массива, если мне нужно их упорядочить исходя из элементов структуры?
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
30.04.2012, 12:43     Сортировка, не изменяя структуру #8
Цитата Сообщение от nake Посмотреть сообщение
а потом как упорядочить элементы массива, если мне нужно их упорядочить исходя из элементов структуры?
Либо самостоятельно написать процедуру сортировки, которая сортирует порядковые номера, сравнивая исходные данные под этими номерами, либо воспользоваться стандартным std::sort с собственным предикатом сравнения. Второе проще, но требует определённых знаний:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Struct {
    int foo;
    float bar;  // Сортировка производится по этому полю
    friend operator << (std::ostream&, const Struct&);  // стандартный вывод
};
 
std::vector<size_t> sortIndex(const std::vector<Struct>& array)
{
    std::vector<size_t> index(array.size());  // вектор порядковых номеров имеет тот же размер, что и массив
    std::iota(index.begin(), index.end(), 0);  // заполнение порядковыми номерами
    std::sort(index.begin(), index.end(), [&array] (size_t idx1, size_t idx2) {return array[idx1].bar < array[idx2].bar;});
    return index;
}
 
void PrintSortedArray(const std::vector<Struct>& array)  // Распечатать упорядоченный массив
{
    const std::vector<size_t> index = sortIndex(array);
    std::for_each(index.begin(), index.end(), [&array] (size_t idx) -> void {std::cout << idx << " - " << array[idx] << std::endl;});
}
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 12:46     Сортировка, не изменяя структуру #9
Попробую изложить, что мне приходит в голову.
Итак,
Шаг 1: (можно сделать один раз)
Создаём вспомогательный массив ARR1, размером по количеству записей N. Каждый элемент этого массива содержит номер записи, последовательно от 0 до N-1.
Шаг 2:
Сортируем этот массив, но в качестве критерия сортировки используем интересующее поле в записи с номером, равным значению очередного элемента.
Шаг 3:
Создаём массив "правильных индексов" ARR2 следующим образом.
C++
1
2
for (int i = 0; i < N ++i)
    ARR2[ARR1[i]] = i + 1;
Всё. В ARR2 содержатся индексы, отсортированные в нужном порядке. Первый индекс соответствует первой записи, второй второй и т. д.
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 13:52  [ТС]     Сортировка, не изменяя структуру #10
Nick Alte, спасибо, но я такое пока не проходил

grizlik78, пойду пробовать

Добавлено через 1 час 0 минут
grizlik78, что то ничего не получается, может вы поможете?
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 14:10     Сортировка, не изменяя структуру #11
Ну я предполагал как-то так:
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
N = 30; // реальное число записей
// заполняем вспомогательный массив
for (int i = 0; i < N; ++i)
    ARR1[i] = i;
// ...
// сортируем вспомогательный массив по маршруту
// (надеюсь сортировка рабочая :) давно я пузырька не разглядывал)
case 51: for(int i=0;i<N;i++)
    {
            for(int j=i+1;j<N;j++)
            {
                    if(a[ARR1[i]].number>a[ARR1[j]].number)
                    {
                           temp=ARR1[i];
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    };
    // получаем индексы (начиная с единицы)
    for (int i = 0; i < N ++i)
         ARR2[ARR1[i]] = i + 1;
    break;
}
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 14:28  [ТС]     Сортировка, не изменяя структуру #12
grizlik78, спасибо, пойду разбираться

Добавлено через 13 минут
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
void sort(int i)    //ГґГіГ*êöèÿ ñîðòèðîâêè Г¤Г*Г*Г*ûõ
{
int n,N=30,temp,button,ARR1[30],ARR2[30];
for (int i = 0; i < N; ++i)
    ARR1[i] = i;
printf("\nMenu");                 
printf("\n1.Brand");
printf("\n2.Date");
printf("\n3.Number");
printf("\n\nTo exit, press Esc \n\n");
button=getch(); 
 
if(button==29) ;
 
switch(button)      //Âûáîð äåéñòâèÿ
{ 
case 49: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[ARR1[i]].brand>a[ARR1[j]].brand)
                    {
                           temp=ARR1[i];;
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    }; for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;
         break;
case 50: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[ARR1[i]].date>a[ARR1[j]].date)
                    {
                           temp=ARR1[i];
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    };for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;break;
case 51: for(int i=0;i<30;i++)
    {
            for(int j=i+1;j<30;j++)
            {
                    if(a[ARR1[i]].number>a[ARR1[j]].number)
                    {
                           temp=ARR1[i];
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    };for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;
         break;
}
}
вот получилась такая функция, но всё равно не сортирует
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 14:40     Сортировка, не изменяя структуру #13
Ну так функция showing должна выводить не i+1, а ARR2[i], а для этого этот массив должен быть доступен из той функции. Можно его глобальным сделать, хотя я стараюсь избегать глобальных переменных. Ну и N наверное не всегда 30, а в зависимости от числа имеющихся записей. Хотя я тут не вникал, может их всегда 30?

Добавлено через 2 минуты
Похоже там N=i

Добавлено через 1 минуту
только плохое это название для параметра. обычно i это переменная цикла и здесь они пересекаются.
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 14:49  [ТС]     Сортировка, не изменяя структуру #14
блин, не могли бы вы исправить, а то я уже не могу понять ничего

Добавлено через 2 минуты
кличество записей всегда 30
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 14:57     Сортировка, не изменяя структуру #15
У меня всё-равно негде проверить работу
Где-нибудь вначале, до main() объявляем массив
C++
1
int ARR2[30];
В начале программы его стоит инициализировать
C++
1
2
for (int i = 0; i < N; ++i)
     ARR2[i] = i + 1;
В функции showing выводим номер из этого массива
C++
1
2
printf("|%-2d|%-10s|%-10s|%-3s   |\n",ARR2[i],a[i].brand,a[i].date,
a[i].number);
Ну и функция сортировки
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
void sort(int N)    //функция сортировки данных
{
int n,temp,button,ARR1[30];
for (int i = 0; i < N; ++i)
    ARR1[i] = i;
printf("\nMenu");                 
printf("\n1.Brand");
printf("\n2.Date");
printf("\n3.Number");
printf("\n\nTo exit, press Esc \n\n");
button=getch(); 
 
if(button==29) ;
 
switch(button)      //Выбор действия
{ 
case 49: for(int i=0;i<N;i++)
    {
            for(int j=i+1;j<N;j++)
            {
                    if(a[ARR1[i]].brand>a[ARR1[j]].brand)
                    {
                           temp=ARR1[i];;
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    }; for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;
         break;
case 50: for(int i=0;i<N;i++)
    {
            for(int j=i+1;j<N;j++)
            {
                    if(a[ARR1[i]].date>a[ARR1[j]].date)
                    {
                           temp=ARR1[i];
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    };for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;break;
case 51: for(int i=0;i<N;i++)
    {
            for(int j=i+1;j<N;j++)
            {
                    if(a[ARR1[i]].number>a[ARR1[j]].number)
                    {
                           temp=ARR1[i];
                           ARR1[i]=ARR1[j];
                           ARR1[j]=temp;
                    }
            }
    };for (int i = 0; i < N; ++i)
         ARR2[ARR1[i]] = i + 1;
         break;
}
}
Добавлено через 2 минуты
Несколько раз пришлось отредактировать, но теперь, вроде, окончательный вариант
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 15:12  [ТС]     Сортировка, не изменяя структуру #16
C++
1
2
for (int i = 0; i < N; ++i)
     ARR2[i] = i + 1;
где должно быть это? в маине?
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 15:15     Сортировка, не изменяя структуру #17
Да, где-то в начале главной функции.

Добавлено через 1 минуту
Только как раз в этом месте цикл должен бы быть до 30, а не до N. Копи-паста подвела
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 15:22  [ТС]     Сортировка, не изменяя структуру #18
grizlik78, извините за назойливость, но всё равно не работает
grizlik78
Эксперт С++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,960
30.04.2012, 16:12     Сортировка, не изменяя структуру #19
Вот такого типа сравнения неправильные.
C++
1
if(a[ARR1[i]].number>a[ARR1[j]].number)
Я не посмотрел сразу, что number это массив символов. Здесь сравниваются адреса массивов, а не содержимое.
Сравнивать надо как-то так:
C++
1
if (strcmp(a[ARR1[i]].number, a[ARR1[j]].number) > 0)
Добавлено через 1 минуту
правда здесь будут сравниваться строки, а не числа
100 > 10, но при этом 100 < 11

Добавлено через 1 минуту
Чтобы сравнивать числовые значения как числа их надо будет преобразовывать в числа
Но для строк как раз strcmp подойдёт
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.04.2012, 16:16     Сортировка, не изменяя структуру
Еще ссылки по теме:

Как правильно написать функцию, которая редактирует структуру по полю Name и возвращает новую, исправленную структуру?.. C++
Как создать структуру-список, поля которой — ссылка на такую же структуру C++
Описать структуру с именем STUDENT. Не работает сортировка C++

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

Или воспользуйтесь поиском по форуму:
nake
 Аватар для nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 16:16  [ТС]     Сортировка, не изменяя структуру #20
спасибо, при сравнении номера просто введу нужные числа
Yandex
Объявления
30.04.2012, 16:16     Сортировка, не изменяя структуру
Ответ Создать тему
Опции темы

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