Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
1

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

30.04.2012, 11:05. Просмотров 978. Ответов 21
Метки нет (Все метки)

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;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2012, 11:05
Ответы с готовыми решениями:

Сортировка массива указателей на структуру
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;string&gt; using namespace...

Описать структуру с именем STUDENT. Не работает сортировка
Вот задача: 1 .Описать структуру с именем STUDENT,содержащую следующие поля: ...

запись в файл, не изменяя размер самого файла
int stream::write(block blocks, int numOfBlocks,const char *data){ int...

Как создать структуру-список, поля которой — ссылка на такую же структуру
Суть вопроса в том, как создать структуру-список, поля которой - ссылка на сл....

Как правильно написать функцию, которая редактирует структуру по полю Name и возвращает новую, исправленную структуру?..
Нужно отредактировать структуру по выбору пользователя. Проблема заключается в...

21
Venzo
125 / 123 / 16
Регистрация: 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;
0
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
Вот так мне нужно, чтобы порядковый инлекс менялся
0
Venzo
125 / 123 / 16
Регистрация: 03.07.2011
Сообщений: 354
30.04.2012, 11:53 4
до сортировки
a[1] = /*икарус*/;
a[2] = /*маз*/;
после
a[2] = /*икарус*/;
a[1] = /*маз*/;
так чтоли? не понятно, что вы хотите сделать)
0
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 12:07  [ТС] 5
да не, так вы поменяете их местами в струтуре, а по заданию так нельзя, нужно просто чтобы в таблице(которая в функции показа) поменялся порядковый номер, т.е к примеру было
1
2
3
4
а отсортировали по какому-нибудь критерию и стало
3
1
4
2
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
30.04.2012, 12:11 6
Создавайте отдельный массив с порядком. Других вариантов нет.
0
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 12:23  [ТС] 7
Цитата Сообщение от Toshkarik Посмотреть сообщение
Создавайте отдельный массив с порядком. Других вариантов нет.
а потом как упорядочить элементы массива, если мне нужно их упорядочить исходя из элементов структуры?
0
Nick Alte
Эксперт С++
1647 / 1019 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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;});
}
1
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
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 содержатся индексы, отсортированные в нужном порядке. Первый индекс соответствует первой записи, второй второй и т. д.
1
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 13:52  [ТС] 10
Nick Alte, спасибо, но я такое пока не проходил

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

Добавлено через 1 час 0 минут
grizlik78, что то ничего не получается, может вы поможете?
0
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
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;
}
1
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;
}
}
вот получилась такая функция, но всё равно не сортирует
0
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
30.04.2012, 14:40 13
Ну так функция showing должна выводить не i+1, а ARR2[i], а для этого этот массив должен быть доступен из той функции. Можно его глобальным сделать, хотя я стараюсь избегать глобальных переменных. Ну и N наверное не всегда 30, а в зависимости от числа имеющихся записей. Хотя я тут не вникал, может их всегда 30?

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

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

Добавлено через 2 минуты
кличество записей всегда 30
0
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
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 минуты
Несколько раз пришлось отредактировать, но теперь, вроде, окончательный вариант
1
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;
где должно быть это? в маине?
0
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
30.04.2012, 15:15 17
Да, где-то в начале главной функции.

Добавлено через 1 минуту
Только как раз в этом месте цикл должен бы быть до 30, а не до N. Копи-паста подвела
1
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 15:22  [ТС] 18
grizlik78, извините за назойливость, но всё равно не работает
0
grizlik78
Эксперт С++
1990 / 1480 / 194
Регистрация: 29.05.2011
Сообщений: 3,063
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 подойдёт
1
nake
0 / 0 / 0
Регистрация: 30.11.2011
Сообщений: 33
30.04.2012, 16:16  [ТС] 20
спасибо, при сравнении номера просто введу нужные числа
0
30.04.2012, 16:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.04.2012, 16:16

Упорядочить заданную последовательность по убыванию, изменяя элементы последовательности
Прошу помочь в задаче на функции. Задание в приложении

Ввод данных в структуру через указатель на структуру
#include &quot;stdafx.h&quot; #include &quot;ctime&quot; #include &quot;iostream&quot; #pragma...

Получить заданное слово, изменяя в исходном слове по одной букве
Ребят, прошу помощи! Есть задача: Дано исходное и конечное слово равной...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru