2015-01-04 3 views
0

В настоящее время я работаю над небольшим проектом над зимним перерывом и столкнулся с некоторыми проблемами.Проблемы с алфавитом массива структур. Работает от Z до A, но не от A до Z

Вот структура, что я работаю с:

struct student{ 
string last_name; 
string first_name; 
double exams[NUM_EXAMS]; 
double average; 
char letter_grade; 
bool passed;}; 

Я пытаюсь в алфавитном порядке по фамилиям от А до Z. Здесь функция в алфавитном порядке, а также функция замены он вызывает:

void alphabetize(student class_list[], int count) 
{ 
    for (int pass = 0; pass < count; pass++) 
     for (int x = 0; x < count - pass; x++) 
      if (class_list[x].last_name < class_list[x + 1].last_name) 
       swap(class_list, x); 
} 

void swap(student class_list[], int x) 
{ 
    student temp[MAX_STUDENTS]; 

    temp[x] = class_list[x]; 
    class_list[x] = class_list[x + 1]; 
    class_list[x + 1] = temp[x]; 
} 

Это работает прекрасно и упорядочивается по алфавиту массива структур в обратном порядке от Z до A.

Здесь несортированный оригинальный выход:

Jones  John 87 66 92 88 83.25 B Pass 
    Smith  Peter 55 66 63 58 60.5 D Pass 
    Quest  Nicole 79 89 99 98 91.25 A Pass 
     Wu   Li 98 99 100 91 97 A Pass 
    West  Vincent 80 80 88 89 84.25 B Pass 
McCartin  Susan 80 90 100 85 88.75 B Pass 
Ibrahima  Shuhuru 45 65 54 60 56 F Fail 
    Burns Antoinette 90 90 90 90 90 A Pass 
     Ng Lawrence 100 100 90 76 91.5 A Pass 
Ziggler  Bertha 65 55 58 58 59 F Fail 
Ionella  Jean 100 100 100 100 100 A Pass 
    Vogler  Samuel 40 50 60 70 55 F Fail 
    Perry   Jim 67 87 76 54 71 C Pass 

и здесь выход, используя

if (class_list[x].last_name < class_list[x + 1].last_name) 

в функции в алфавитном порядке.

Ziggler  Bertha 65 55 58 58 59 F Fail 
     Wu   Li 98 99 100 91 97 A Pass 
    West  Vincent 80 80 88 89 84.25 B Pass 
    Vogler  Samuel 40 50 60 70 55 F Fail 
    Smith  Peter 55 66 63 58 60.5 D Pass 
    Quest  Nicole 79 89 99 98 91.25 A Pass 
    Perry   Jim 67 87 76 54 71 C Pass 
     Ng Lawrence 100 100 90 76 91.5 A Pass 
McCartin  Susan 80 90 100 85 88.75 B Pass 
    Jones  John 87 66 92 88 83.25 B Pass 
Ionella  Jean 100 100 100 100 100 A Pass 
Ibrahima  Shuhuru 45 65 54 60 56 F Fail 
    Burns Antoinette 90 90 90 90 90 A Pass 

Если я переключаю

if (class_list[x].last_name < class_list[x + 1].last_name) 

в функции в алфавитном порядке

if (class_list[x].last_name > class_list[x + 1].last_name) 

Я думал, что это позволит решить проблему и сортировки массива от А до Z, а не Z до A. Это то, что я получаю как результат:

    -6.27744e+066-6.27744e+066-6.27744e+066-6.27744e+066-6.2 
7744e+066 ═ Pass 
    Burns Antoinette 90 90 90 90 90 A Pass 
Ibrahima  Shuhuru 45 65 54 60 56 F Fail 
Ionella  Jean 100 100 100 100 100 A Pass 
    Jones  John 87 66 92 88 83.25 B Pass 
McCartin  Susan 80 90 100 85 88.75 B Pass 
     Ng Lawrence 100 100 90 76 91.5 A Pass 
    Perry   Jim 67 87 76 54 71 C Pass 
    Quest  Nicole 79 89 99 98 91.25 A Pass 
    Smith  Peter 55 66 63 58 60.5 D Pass 
    Vogler  Samuel 40 50 60 70 55 F Fail 
    West  Vincent 80 80 88 89 84.25 B Pass 
     Wu   Li 98 99 100 91 97 A Pass 

Как вы можете видеть, я сейчас пропущу то, что было бы последним учеником в этом списке, и вместо этого вывод выплевывает эти числа. Я не понимаю, почему он работает в обратном порядке, и я не уверен, как это исправить. Любой совет будет очень благодарен!

EDIT: Благодаря Jarod42 я разработал решение моей проблемы. Это была проблема с границами с x + 1. Вот код, который я использовал для устранения проблемы. Он работает с входным файлом, который у меня есть, но я не уверен, что он будет работать с другим. Если кто-то видит проблему с этим, пожалуйста, дайте мне знать.

void alphabetize(student class_list[], int count) 
{ 
    for (int pass = 0; pass < count; pass++) 
     for (int x = 0; x < count - pass; x++) 
      if (class_list[x].last_name > class_list[x + 1].last_name) 
       if (count > x + 1) 
        swap(class_list, x); 
} 
+0

Упоминайте [пояснения] (http://en.cppreference.com/w/cpp/string/basic_string/operator_cmp) в справочной справке, чтобы объяснить ваше понимание сравнения 'std :: string'? –

+2

Вы получаете индекс за пределы в этом вложенном цикле. Это вызывает неопределенное поведение независимо от того, как вы пытаетесь сортировать массив, поэтому при повторном попытке вы можете получить этот странный вывод даже при сортировке их из Z-A. –

ответ

2

С:

for (int x = 0; x < count - pass; x++) 
    if (class_list[x].last_name < class_list[x + 1].last_name) 

Вы можете иметь из связанного доступа с x + 1 когда pass == 0.

С STL, вы можете просто сделать:

std::sort(std::begin(students), std::end(students), 
      [](const student& lhs, const student& rhs) { 
       return lhs.last_name < rhs.last_name; // and > for the other order 
      }); 
+1

Для удовольствия: ** [даже не используя std :: vector] (http://coliru.stacked-crooked.com/a/bcb8299e1b23ac92) ** :) – sehe

+0

Спасибо за ваш быстрый ответ! Я согласен с тем, что это, скорее всего, проблема с пределами «x + 1». Я только начинаю с C++, и я не знаком с STL. Я бы очень хотел работать с этим, используя то, что мой учитель прошел в прошлом семестре. Есть ли способ, которым я могу использовать функцию подкачки и какую-то отказоустойчивость для проблемы вне границ? –

0

Если вы действительно не хотите использовать стиль C++ (векторы и СТЛ, напримерстанд :: сортировка), попробуйте изменить эту строку:

for (int x = 0; x < count - pass; x++) 

в:

for (int x = 0; x < count - pass - 1; x++) 

Вы должны понимать инварианты. Ваш алгоритм сортировки гарантирует, что на каждом шаге пройти, у вас есть последние pass позиции в вашем массиве отсортированы. Вот где -pass происходит от. То, что -1 связано с тем, что на каждом шаге в этом цикле for вы сравниваете текущую позицию со следующей.

Однако я настоятельно рекомендую вам использовать зЬй :: вектор и зЬй :: сортировать, если вы пытаетесь научить себя алгоритм сортировки.

+0

Спасибо за ваш ответ. Я пытаюсь завершить эту программу, используя то, чему меня учили в классе, и не слишком быстро продвигаюсь вперед. Мы еще не перешли ** std :: vector ** или ** std :: sort **, и часть задания требует, чтобы мы писали нашу собственную функцию алфавита. Я редактировал свой основной пост с решением, которое я придумал внизу. Я хотел бы услышать ваши мысли. ** РЕДАКТИРОВАТЬ **: Я попытался использовать код, который вы предложили, с count-pass-1, и это тоже работает. Есть ли разница в стабильности между кодом, который я редактировал в моем главном сообщении, и кодом, который вы предложили? –

+0

Что касается функциональности, нет, нет разницы. Это потому, что count> x + 1 <=> x

Смежные вопросы