Bubblesort Struct Array с перечисленным направлением / типом - PullRequest
0 голосов
/ 10 октября 2018

У меня есть функция sort, передается массив структур.

Структуры содержат строки.

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;
            }
          }
      }
    }
}

Итак;Я передаю sort моего массива 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; это просто переворачивание массива.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Ваша функция сравнения в основном отсутствует, но части, которые там присутствуют, предполагают, что у вас нет пути, чтобы когда-либо возвращать определенную false, которая является обязательной для правильного компаратора.

Во-вторых, вы вызываете order ofаргументы неверны.Аргумент «правой» стороны должен быть first , второй «левой» стороной.если компаратор отвечает 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
0 голосов
/ 10 октября 2018

Я добавил 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;
    }
}

См. Онлайн demo .

...