【问题标题】:Issues alphabetizing an array of structs. Works from Z to A but not from A to Z按字母顺序排列结构数组的问题。从 Z 到 A 工作,但不是从 A 到 Z
【发布时间】:2015-01-04 22:38:26
【问题描述】:

我目前正在寒假做一个小项目,但遇到了一些问题。

这是我正在使用的结构:

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

我正在尝试按姓氏从 A 到 Z 进行字母排序。这是Alphabetize 函数以及它调用的交换函数:

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)

在Alphabetize函数中。

 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)

在Alphabetize函数中

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

我认为它可以解决问题并将数组从 A 排序到 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

如您所见,我现在错过了该列表中的最后一个学生,而是输出了这些数字。我不明白为什么它会反向工作,我不确定如何解决这个问题。任何建议将不胜感激!

编辑:感谢 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);
}

【问题讨论】:

  • 参考文献中的these explanations能否解释你对std::string比较的理解?
  • 在嵌套的 for 循环中,您的索引超出了范围。无论您尝试如何对数组进行排序,它都会导致未定义的行为,因此在另一次尝试中,即使从 Z-A 对它们进行排序,您也可能会得到奇怪的输出。

标签: c++ arrays function struct alphabetized


【解决方案1】:

与:

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

pass == 0 时,您可能拥有x + 1 的越界访问权限。

使用 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
          });

【讨论】:

  • 为了好玩:not even using std::vector :)
  • 感谢您的快速回答!我同意这很可能是“x + 1”的越界问题。我刚从 C++ 开始,我对 STL 不熟悉。我真的很想用我老师上学期讲过的东西来解决这个问题。有什么方法可以使用交换功能和某种故障安全解决越界问题吗?
【解决方案2】:

如果您真的不想使用 C++ 样式(vectorsstl,例如 std::sort),请尝试修改此行:

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

进入:

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

您必须了解不变量。您的排序算法保证在每一步 pass 中,您对数组中的最后一个 pass 位置进行排序。这就是 -pass 的由来。 -1 是因为在这个 for 循环中的每一步,您都会将当前位置与下一个位置进行比较。

但是,我强烈建议您使用 std::vectorstd::sort,除非您想自学排序算法。

【讨论】:

  • 感谢您的回复。我正在尝试使用我在课堂上所教的内容来完成这个程序,并且不要太快前进。我们还没有研究过 std::vectorstd::sort 并且部分任务要求我们编写自己的Alphabetize 函数。我用我在底部提出的解决方案编辑了我的主要帖子。我很想听听你的想法。 编辑:我尝试使用您建议的代码 count - pass - 1 并且效果也很好。我在主帖中编辑的代码和你建议的代码在稳定性上有什么区别吗?
  • 就功能而言,不,没有区别。那是因为 count > x + 1 x if 语句会导致一些延迟。此外,您进行 step 不必要的比较:您在每一步比较 passpass + 1 位置,即使您的算法保证您的最后一个 通过位置排序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
相关资源
最近更新 更多