c - 无法正确排序字符串数组

标签 c sorting c-strings

假设我有两个数组,其中一个包含某些数字,另一个包含与这些数字对应的名称,以 sums[i]names 关联的方式[i].

#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

int main()
{
  char *names[] = {"William","Olivia","Willaim","Olivai","Lily","Lyli"};
  int sums[6] = {58, 48, 58, 48, 30, 30};
  int i, j, s = 6;
  char *temp_char;
  int temp_int;
  for(i=0 ; i < s-1 ; i++){
    for (j=0; j<s-i; j++){
      if (sums[j]<sums[j+1]){
        temp_char = names[j+1];
        temp_int = sums[j+1];
        names[j+1] = names[j];
        sums[j+1] = sums[j];
        names[j] = temp_char;
        sums[j] = temp_int;
      }

      if ((sums[j] == sums[j+1]) && (strcmp(names[j], names[j+i])>0)) {
        temp_char = names[j+1];
        names[j+1] = names[j];
        names[j] = temp_char;
      }
    }
  }

  for (i = 0; i<s; i++){
    printf("%d ", sums[i]);
    printf("%s\n", names[i]);
  }

  return 0;
}

这是原始代码的一部分,已编译但未真正正确排序。然而,这个突然返回段错误。

为什么我突然收到这个错误,为什么排序不起作用?

最佳答案

您的程序没有执行到段错误。 (至少在 Ubuntu 中通过 GCC 7.2 编译和执行时)。 但是,您可能需要关注一些要点,以便让您的排序部分顺利进行。

  1. 关注这一行:for (j=0; j<s-i; j++) . 在这里,j 的最终值将获得 5. 怎么样?您已声明 s在初始化期间为 6,最小值为 i为 0。所以默认情况下 j可以在 0 到 5 之间(注意 j 必须小于 s-i ,因此 for 循环不会让它超过 5)。但它如何影响你的逻辑?现在如果 j 的最大值获取的是 5,则 j+1 的最大值将是 6。因此,当您在最末端(在 j=5 处)执行交换时,您可能会在数组中得到一个垃圾值。只要多次执行代码,您就会注意到这一事实。要解决此问题,只需使用 for (j=0; j<s-i-1; j++) .
  2. 现在来到包含这个 (strcmp(names[j], names[j+i])>0) 的行陈述。 您的代码表示您正在以降序方式使用冒泡排序。因此,要在这里发生这种情况,您需要有 (strcmp(names[j+1], names[j])>0) .这将允许您将第 (j+1) 个索引处的字符串与第 j 个索引处的字符串进行比较。如果第 (j+1) 个索引处的字符串大于第 j 个索引处的字符串,那么您可以进行交换(因为您希望以降序方式进行排序)。

为了将上述想法付诸实践,我们开始吧:

#include <stdio.h>
#include <string.h>

int main()
{

    char *names[] = {"William","Olivia","Willaim","Olivai","Lily","Lyli"};
    int sums[6] = {58, 48, 58, 48, 30, 30};
    int i, j, s = 6;
    char *temp_char;
    int temp_int;
    for(i=0 ; i < s ; i++){
          for (j=0; j<s-i-1; j++){ //Change 1
              if (sums[j]<sums[j+1]){
                  temp_char = names[j+1];
                  temp_int = sums[j+1];
                  names[j+1] = names[j];
                  sums[j+1] = sums[j];
                  names[j] = temp_char;
                  sums[j] = temp_int;
              }
              if ((sums[j] == sums[j+1]) && (strcmp(names[j+1], names[j])>0)) { //Change 2
                  temp_char = names[j+1];
                  names[j+1] = names[j];
                  names[j] = temp_char;
              }           
          }
    }

    for (i = 0; i<s; i++){
          printf("%d ", sums[i]);
          printf("%s\n", names[i]);
    }

    return 0;
}

对您的代码的建议:使用 struct结合你的namessums排列在一起。效率方面它看起来并不多,但它会帮助您的代码看起来更简洁。

关于c - 无法正确排序字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57350955/

相关文章:

C scanf 字符串数组

cprinting Ascii 使用整数赋值给 char

c - 几何序列打印……吓坏了

c - 将 gdb 与 alsa-lib-1.1.3 一起使用

c++ - 在取消定义宏函数之前使用/将宏变量的值复制到宏函数中 : is it possible?

c - 如何读取字符串直到两个连续的空格?

bash - 在不排序的情况下删除变量上的重复项

javascript - 从数组中提取数据并将其包含到javascript中的对象中

javascript - 如何在javascript中对多维数组进行排序

c - 为什么我的程序在将内存分配给双指针 C 时会产生段错误