【问题标题】:String array Sorting C字符串数组排序 C
【发布时间】:2016-09-04 10:25:09
【问题描述】:

我一直试图让这个程序按列索引对二维字符串数组进行排序。

我这样初始化这个二维数组:

char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                         {"America", "Cycling", "Mens", "Gold"}, 
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"India", "Badminton", "Mens", "Bronze"}};

如果我想按第一列(国家名称)对这个数组进行排序,那么它看起来像这样:

char *str[ROWS][COLS] = {{"America", "Cycling", "Mens", "Gold"}, 
                         {"India", "Badminton", "Mens", "Bronze"}};
                         {"New Zealand", "Swimming", "Womens", "Silver"},   
                         {"Russia", "Boxing", "Mens", "Gold"}};

这是我到目前为止所做的,几乎是正确的,除了排序方法。我在实施时遇到了麻烦。

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

#define ROWS 4
#define COLS 4

void print_array(char *str[][COLS]);
void sort_array(char *str[][COLS], int nrows, int col);

int
main(void) {
    char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                             {"America", "Cycling", "Mens", "Gold"}, 
                             {"New Zealand", "Swimming", "Womens", "Silver"}, 
                             {"India", "Badminton", "Mens", "Bronze"}};
    int col;

    /* array before sorting */
    printf("Before: \n");
    print_array(str);

    /*choosing column index to sort by*/
    printf("\nChoose which column index you wish to sort by: ");
    if (scanf("%d", &col) != 1) {
        printf("Invalid input\n");
        exit(EXIT_FAILURE);
    }

    sort_array(str, ROWS, col);

    /* array after sorting */
    printf("\nAfter: \n");
    print_array(str);

return 0;
}

void
print_array(char *str[][COLS]) {
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%s  ", str[i][j]);
        }
        printf("\n");
    }
}

/*function used for sorting the array */
void
sort_array(char *str[][COLS], int nrows, int col) {
    int i, j;
    char *temp;

    for (i = 0; i < nrows; i++) {
        for (j = i; j < nrows; j++) {
            if(strcmp(str[i][col], str[j][col]) > 0) {
                temp = str[i][col];
                str[i][col] = str[j][col];
                str[j][col] = temp;
            }
        }
    }   
}

我遇到的问题是我的排序算法不是交换行,而是交换该列中的字符串。我也尝试使用insertion sort 算法,但我不确定如何使用二维字符串数组来实现它。

任何帮助将不胜感激:)

【问题讨论】:

    标签: c arrays algorithm sorting


    【解决方案1】:

    从 C11 开始,您可以按如下方式进行:

    int compare_col(const void *a, const void *b, void *ctx) {
        int col = *(int*)ctx;
        return strcmp(((char**)a)[col], ((char**)b)[col]);
    }
    
    /*function used for sorting the array */
    void sort_array(char *str[][COLS], int nrows, int col) {
        qsort_s(str, nrows, sizeof(char*)*COLS, compare_col, &col);
    }
    

    【讨论】:

    • 我相信 qsort_s 仅在附件 K 中,因此即使所有符合 C11 的实现也不一定支持它……有点遗憾,因为比较器的第三个参数是一个有用的补充正如你所展示的那样。
    • 同时,我建议使用sizeof(*str) 而不是sizeof(char*)*COLS 以避免冗余以及类型更改时可能出现的错误。
    【解决方案2】:

    使用qsort,您需要一个比较器函数,将指针作为参数,指向要排序的两个元素。在这种情况下,要排序的元素是二维数组中的一整行。如果您需要改变排序列,您还需要使变量保持全局(否则您需要为每列创建不同的比较器)。

    static int sort_column = 0;
    
    static int compare_rows(const void *a, const void *b) {
        return strcmp(((const char **)a)[sort_column], ((const char **)b)[sort_column]);
    }
    

    然后您只需调用 qsort 并将您的数组和比较器函数作为参数:

    qsort(str, ROWS, sizeof(*str), (compare_rows));
    

    【讨论】:

      【解决方案3】:

      遍历行。比较两行的列,ii + 1。根据需要遍历列并交换两行。重复直到没有交换为止。

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      #define ROWS 4
      #define COLS 4
      
      void print_array(char *str[][COLS]);
      void sort_array(char *str[][COLS], int nrows, int ncols, int col);
      
      int
      main(void) {
          char *str[ROWS][COLS] = {{"Russia", "Boxing", "Mens", "Gold"},
                                   {"America", "Cycling", "Mens", "Gold"},
                                   {"New Zealand", "Swimming", "Womens", "Silver"},
                                   {"India", "Badminton", "Mens", "Bronze"}};
          int col;
          int result = 0;
          int clean = 0;
          /* array before sorting */
          printf("Before: \n");
          print_array(str);
      
          /*choosing column index to sort by*/
          do {
              printf("\nChoose which column index you wish to sort by 0 to %d: ", COLS - 1);
              if ( ( result = scanf("%d", &col)) != 1) {
                  printf("Invalid input\n");
                  if ( result == EOF) {
                      fprintf ( stderr, "problem getting input\n");
                      exit(EXIT_FAILURE);
                  }
                  //clean input stream
                  while ( ( clean = getchar ()) != '\n' && clean != EOF) {}
              }
          } while ( result != 1 || col < 0 || col >= COLS);
      
          sort_array(str, ROWS, COLS, col);
      
          /* array after sorting */
          printf("\nAfter: \n");
          print_array(str);
          return 0;
      }
      
      void
      print_array(char *str[][COLS]) {
          int i, j;
      
          for (i = 0; i < ROWS; i++) {
              for (j = 0; j < COLS; j++) {
                  printf("%s  ", str[i][j]);
              }
              printf("\n");
          }
      }
      
      /*function used for sorting the array */
      void
      sort_array(char *str[][COLS], int nrows, int ncols, int col) {
          int i = 0, j = 0, swap = 0;
          char *temp;
      
          do {
              swap = 0;
              for ( i = 0; i < nrows - 1; i++) {//iterate through rows
                  if ( strcmp( str[i][col], str[i + 1][col]) > 0) {//compare col for row i and i+1
                      for ( j = 0; j < ncols; j++) {//iterate through cols and swap rows
                          temp = str[i][j];
                          str[i][j] = str[i + 1][j];
                          str[i + 1][j] = temp;
                      }
                      swap = 1;
                  }
              }
          } while ( swap);//loop until no swaps
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-02
        • 2023-03-03
        • 1970-01-01
        • 2012-08-31
        • 1970-01-01
        • 2014-07-11
        相关资源
        最近更新 更多