У меня есть функция сортировки, передавая массив структур.
Структуры содержат строки.
struct studentStruct {
string firstName;
string lastName;
int grade;
float GPA;
};
Я передаю этот массив структур в функцию сортировки, а также 2 перечислимых типа.
enum sortField {eFirstName, eLastName, eGrade, eGPA};
enum sortDirection {eAscending, eDescending};
Теперь я должен использовать Bubblesort и функцию compData, поэтому;
void sort( studentStruct s[], enum sortField field, int length, sortDirection d)
{
for(int i = 0; i < length - 1; i++)
{
for(int j = 0; j < length - 1 - i; j++)
{
if(compData(s[j], s[j+1], field, d) == true)
{
swap(s[j], s[j+1]);
cout << "SWAP" << endl;
}
}
}
}
bool compData( studentStruct s1, studentStruct s2, sortField field, sortDirection direction)
{
switch(field)
{
case eFirstName:
{
string f1 = s1.firstName;
string f2 = s2.firstName;
switch(direction)
{
case eAscending:
{
if(f2 < f1)
return true;
}
case eDescending:
{
if(f2 > f1)
return true;
}
}
}
}
}
Так; Я прохожу сортировать мой массив Structs s[]
это вызывает compData
решить, стоит ли переключаться s[j]
а также s[j+1]
, compData
смотрит на перечисленные значения, чтобы решить, как мы сравниваем s[j]
а также s[j+1]
, выбирает сортировать по eFirstName
, eAscending
и сортировать соответственно.
Но на самом деле я прохожу sort(s[], eFirstName, 10, eAscending)
и я получаю неправильно отсортированный беспорядок. Для 5 входов M, I, K, O, N,
Я выхожу
N, O, K, I, M;
это просто перевернуть массив.
Ваша функция сравнения в основном отсутствует, но части, которые там есть, предполагают, что у вас нет пути, чтобы когда-либо вернуть окончательный false
, что является обязательным для правильного компаратора.
Во-вторых, вы называете порядок аргументов неверным. «Правая» аргументация должна быть первый, «левая» сторона вторая. если компаратор отвечает true, они находятся в неправильном порядке и должны быть заменены.
Обращаясь к обоим из них (и предоставляя вам улучшенную пузырьковую сортировку с ранним обнаружением выхода на уже отсортированных последовательностях), результат работает как задумано:
#include <iostream>
#include <algorithm>
enum sortField {eFirstName, eLastName, eGrade, eGPA};
enum sortDirection {eAscending, eDescending};
struct studentStruct {
std::string firstName;
std::string lastName;
int grade;
float GPA;
};
bool compData( studentStruct s1, studentStruct s2, sortField field, sortDirection direction)
{
bool result = false;
switch(field)
{
case eFirstName:
switch(direction)
{
case eAscending:
result = s1.firstName < s2.firstName;
break;
case eDescending:
result = s2.firstName < s1.firstName;
break;
}
break;
case eLastName:
switch(direction)
{
case eAscending:
result = s1.lastName < s2.lastName;
break;
case eDescending:
result = s2.lastName < s1.lastName;
break;
}
break;
case eGrade:
switch(direction)
{
case eAscending:
result = s1.grade < s2.grade;
break;
case eDescending:
result = s2.grade < s1.grade;
break;
}
break;
case eGPA:
switch(direction)
{
case eAscending:
result = s1.GPA < s2.GPA;
break;
case eDescending:
result = s2.GPA < s1.GPA;
break;
}
break;
}
return result;
}
void sort( studentStruct s[], enum sortField field, int length, sortDirection d)
{
bool swapped = true;
while (swapped && length-- > 0)
{
swapped = false;
for (int i=0; i<length; ++i)
{
if (compData(s[i+1], s[i], field, d))
{
std::cout << "SWAP" << '\n';
std::swap(s[i+1], s[i]);
swapped = true;
}
}
}
}
int main()
{
studentStruct students[] = { {"M"}, {"I"}, {"K"}, {"O"}, {"N"} };
sort(students, eFirstName, 5, eAscending);
for (auto const& s : students)
std::cout << s.firstName << '\n';
}
Выход
SWAP
SWAP
SWAP
I
K
M
N
O
я добавил return false
для else
часть условных заявлений в compData
и работает как положено.
switch(direction)
{
case eAscending:
{
if(f2 < f1)
return true;
else
return false;
}
case eDescending:
{
if(f2 > f1)
return true;
else
return false;
}
}
Смотреть онлайн демонстрация.