【问题标题】:How to sort array of strings in ascending order in C如何在C中按升序对字符串数组进行排序
【发布时间】:2018-06-06 04:03:42
【问题描述】:

问题

我已经制作了与其他类似的排序程序

https://beginnersbook.com/2015/02/c-program-to-sort-set-of-strings-in-alphabetical-order/

但是我制作的程序不起作用。 我认为两者都是一样的,但我的程序给了我废物输出。

另外我想知道在其他程序中计数设置为 5,它应该从 0 开始需要 6 个输入,但它只得到 5,如何?

我的计划

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

int main() {

char str[4][10],temp[10];
int i,j;
printf("Enter strings one by one : \n");
for(i=0;i<5;i++)
    scanf("%s",str[i]);

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

printf("\nSorted List : ");
for(i=0;i<5;i++)
    printf("\n%s",str[i]);
printf("\n\n");

return 0;

}

【问题讨论】:

  • 您将六个字符串存储在一个数组中,只有四个足够的空间,并且没有检查这些字符串的长度(必须为 9 个字符或更少)。难怪它不起作用。
  • 您有一个 4 元素数组,并且您正尝试将 6 个元素放入其中。尝试使用 'char str[6][10],temp[10];'以获得更好的体验。
  • 4 个元素?我认为数组从 0 开始,所以它应该是 5 元素数组(重新编辑以存储 5)
  • 你认为错了:一个 [4] 数组有 4 个元素,有效索引是 0、1、2 和 3。请参阅我之前的建议。您的算法可能有效,但它会破坏变量,并且之后可能会崩溃。这正是 C 被认为是“危险的”的原因。
  • 谢谢,tevemadar。现在我只想知道其他程序如何在输入 5 上仅存储 5 个元素,因为从 0 到 5 的计数 bcoz 意味着执行循环 6 次,但循环仅执行 5 次供输入。

标签: c arrays string sorting


【解决方案1】:

使用qsort()

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

int pstrcmp( const void* a, const void* b )
{
  return strcmp( *(const char**)a, *(const char**)b );
}

int main()
{
  const char* xs[] =
  {
    "Korra",
    "Zhu Li",
    "Asami",
    "Mako",
    "Bolin",
    "Tenzin",
    "Varrick",
  };
  const size_t N = sizeof(xs) / sizeof(xs[0]);

  puts( "(unsorted)" );
  for (int n = 0; n < N; n++)
    puts( xs[ n ] );

  // Do the thing!
  qsort( xs, N, sizeof(xs[0]), pstrcmp );

  puts( "\n(sorted)" );
  for (int n = 0; n < N; n++)
    puts( xs[ n ] );
}

请不要使用冒泡排序。在 C 语言中,您真的不必在特殊需要之外编写自己的排序算法。

【讨论】:

    【解决方案2】:

    这是一个程序,它将对您输入的字符串进行排序和打印。回答有点晚,但以防万一其他人有类似的问题。

    // This program will sort strings into either ascending or descending order
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_SIZE            1000
    #define EQUAL               0
    #define ASCENDING           0
    #define DESCENDING          1
    
    // Function prototypes
    void swap_str(char str1[], char str2[]);
    void sort_strings(char str[MAX_SIZE][MAX_SIZE], int len, int order_type);
    void print_2d_array(char str[MAX_SIZE][MAX_SIZE], int len);
    
    int main(void) {
    
        int order_type;
        char str[MAX_SIZE][MAX_SIZE];
    
        // User selecting the order type
        printf("-----------[Order Type]-----------\n");
        printf("Sort your strings in ascending or descending order?\n");
        printf("0 = Ascending | 1 = descending\n");
    
        scanf("%d", &order_type);
        if (order_type != ASCENDING && order_type != DESCENDING) {
            printf("Please enter 0 or 1\n");
            exit(1);
        }
    
        // User inputting their strings
        printf("---------[Enter Strings]----------\n");
        printf("Enter Strings one by one.\n");
        printf("Max Strings: %d | Max String Len: %d\n", MAX_SIZE, MAX_SIZE);
    
        int i = 0;
        while ((i < MAX_SIZE) && (scanf("%s", str[i]) == 1)) i++;
        if (i == MAX_SIZE) printf("You reached the maximum strings allowed\n"); 
    
        // Program output of the sorted strings    
        printf("---------[Sorted Strings]---------\n");
        sort_strings(str, i, ASCENDING);
        print_2d_array(str, i);
    
        return 0;
    }
    
    // Swaps two strings (assuming memory allocation is already correct)
    void swap_str(char str1[], char str2[]) {
    
        char temp[MAX_SIZE];
    
        strcpy(temp, str1);
        strcpy(str1, str2);
        strcpy(str2, temp);
    
    }
    
    // Will sort a 2D array in either descending or ascending order,
    // depending on the flag you give it
    void sort_strings(char str[MAX_SIZE][MAX_SIZE], int len, int order_type) {
    
        int i = 0;
        while (i < len) {
    
            int j = 0;
            while (j < len) {
    
                if ((order_type == ASCENDING) &&
                    (strcmp(str[i], str[j]) < EQUAL)) {
    
                    swap_str(str[i], str[j]);
                } else if ((order_type == DESCENDING) &&
                    (strcmp(str[i], str[j]) > EQUAL)) {
    
                    swap_str(str[i], str[j]);
                }
    
                j++;
            }
    
            i++;
        }
    
    }
    
    // Will print out all the strings 2d array
    void print_2d_array(char str[MAX_SIZE][MAX_SIZE], int len) {
    
        int i = 0;
        while (i < len) {
            printf("%s\n", str[i]);
            i++;
        }
    }
    

    示例(升序):

    -----------[Order Type]-----------
    Sort your strings in ascending or descending order?
    0 = Ascending | 1 = descending
    0
    ---------[Enter Strings]----------
    Enter Strings one by one.
    Max Strings: 1000 | Max String Len: 1000
    Mango
    Watermelon
    Apple
    Banana
    Orange
    // I pressed CTRL+D here (Linux) or CTRL+Z then enter (on Windows). Essentially triggering EOF. If you typed the MAX_SIZE it would automatically stop.
    ---------[Sorted Strings]---------
    Apple
    Banana
    Mango
    Orange
    Watermelon
    

    【讨论】:

    • 请将该站点用作一般的 CS QA 站点,而不是作业解决站点。不要提供直接的解决方案。在他们不正确的地方引导他们。
    【解决方案3】:

    它应该从 0 开始需要 6 个输入,但它只得到 5,如何?

    这个循环

    for(i=0;i<5;i++)
        scanf("%s",str[i]);
    

    执行 i 为 0, 1, 2, 3, 4 所以循环 5 次。

    如果你想要 6 个循环,那就做

    for(i=0;i<=5;i++)
              ^
              Notice
    

    for(i=0;i<6;i++)
              ^
              Notice
    

    还要注意这一行

    char str[6][10],temp[10];
             ^
             Notice
    

    这样您就可以为 6 个字符串保留内存

    【讨论】:

    • 我认为是因为gets,但是gets所做的只需要5个
    • 非常感谢。
    【解决方案4】:

    这不是一个答案,而是对你refer的代码的一些批评:

    #include<stdio.h>
    #include<string.h>
    int main(){
      int i,j,count;
      char str[25][25],temp[25];
      puts("How many strings u are going to enter?: ");
      scanf("%d",&count);                                        // (1)
    
      puts("Enter Strings one by one: ");
      for(i=0;i<=count;i++)                                      // (2)
        gets(str[i]);
      for(i=0;i<=count;i++)
        for(j=i+1;j<=count;j++){
          if(strcmp(str[i],str[j])>0){
            strcpy(temp,str[i]);
            strcpy(str[i],str[j]);
            strcpy(str[j],temp);
         }
      }
      printf("Order of Sorted Strings:");                        // (3)
      for(i=0;i<=count;i++)
        puts(str[i]);
    
      return 0;
    }
    

    还有批评:

    (1) scanf("%d",&amp;count); 将一个数字读入计数,然后返回。它不消耗换行符(!)

    (2) 这个循环不打印任何东西,只是读取。但是,如果你把

      for(i=0;i<=count;i++){
        printf("%d:",i);
        gets(str[i]);
      }
    

    在它的位置,你会突然看到它要求名称 0...5,只是自动跳过 0。那就是使用换行符的地方,它读取一个空字符串。您也可以让它出现,如果不是将5 放入初始问题,而是放入5 anmoloo7

    (3) 在打印输出中,名称出现在标题Order of Sorted Strings 下方。但是该 printf 中没有换行符。问题是空字符串比任何其他字符串“小”,所以它到达列表的前面,并且首先打印在那里。如果您在初始数字后附加名称的“技巧”,输出看起来会有所不同,将有 6 个名称,其中一个直接附加到标题。

    此外,您可能还从编译器中得到了一些东西:gets 是一个致命的功能,忘记它的存在并使用 fgets 和其他答案中出现的 stdin。

    【讨论】:

      【解决方案5】:

      我有这个我制作的样本:

      #include <stdio.h>
      #include <string.h>
      void main()
      {
        char str[100],ch;
        int i,j,l;
      
             printf("\n\nSort a string array in ascending order :\n");
             printf("--------------------------------------------\n");  
             printf("Input the string : ");
             fgets(str, sizeof str, stdin);
        l=strlen(str);
        /* sorting process */
        for(i=1;i<l;i++)
          for(j=0;j<l-i;j++)
          if(str[j]>str[j+1])
          {
            ch=str[j];
            str[j] = str[j+1];
            str[j+1]=ch;
          }
         printf("After sorting the string appears like : \n");
         printf("%s\n\n",str);
        }
      

      【讨论】:

      • 此代码将对字符数组(一个字符串)进行排序,但问题是对字符串数组进行排序。
      猜你喜欢
      • 1970-01-01
      • 2020-05-24
      • 2012-04-03
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多