0

私は現在、冬休み中に小さなプロジェクトに取り組んでおり、いくつかの問題に遭遇しました。

ここに私が取り組んでいる構造体があります:

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

A から 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 から A ではなく A から Z に並べ替えられると思いました。これが出力として得られるものです。

                    -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

ご覧のとおり、このリストの最後の生徒が何になるかがわかりません。代わりに、出力にこれらの数字が吐き出されています。逆に動作する理由がわかりません。これを修正する方法がわかりません。どんなアドバイスでも大歓迎です!

編集: 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);
}
4

2 に答える 2

2

と:

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

x + 1whenを使用すると、範囲外のアクセスが発生する可能性があります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
          });
于 2015-01-04T22:46:28.127 に答える
0

本当に C++ スタイル (ベクトルstl、たとえば std::sort)を使用したくない場合は、次の行を変更してみてください。

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

の中へ:

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

不変条件を理解する必要があります。ソート アルゴリズムにより、各ステップパスで、配列内の最後のパス位置がソートされることが保証されます。それが-passの由来です。この-1は、この for ループ内の各ステップで、現在の位置を次の位置と比較するという事実によるものです。

ただし、並べ替えアルゴリズムを独学しようとしている場合を除き、 std ::vectorstd::sortを使用することを強くお勧めします。

于 2015-01-04T23:31:34.860 に答える