按字母顺序对字符串列表进行排序 (C)

Posted

技术标签:

【中文标题】按字母顺序对字符串列表进行排序 (C)【英文标题】:Sorting a list of Strings in Alphabetical order (C) 【发布时间】:2017-02-23 07:18:09 【问题描述】:

好的,这是我的问题。一位老师必须随机选择一个学生(从她拥有的学生中)以在期末成绩中获得特殊奖励,为此,她将 N 张从 1 到 N 编号的纸放在一个袋子中,并随机选择一个数字 K ;获奖学生是学生名单中的第 K 个学生。问题是老师不知道哪个数字对应哪个学生,因为她丢失了包含此信息的论文。她所知道的:所有学生的名字,以及他们的数字,从 1 到 N,是按照字母顺序分配的。

因此,我需要获取作为输入的一组姓名,按字母顺序对它们进行排序,然后提供获得特别奖金的学生的姓名,但我在这样做时遇到了麻烦。我编写的程序对除第一个以外的所有名称进行排序。

此外,当我使用 Code::Blocks 运行项目时出现以下警告:

(第 16 行)ISO C90 禁止数组变长 's' [-Wvla] (第 13 行)ISO C90 禁止混合声明和代码 [-Wpedantic]

请告诉我我在这里做错了什么以及是否有更好的方法来对名称进行排序而无需指定数量的名称。

注意:当 N 和 K 等于 0 时,程序应该停止读取输入。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()

    int n, k, i, j=0, aux, numMenorNome;
    char str[]="zzzzzzzzzzzzzzzzzzzz", str2[]="zwyxzzzzzzzzzzzzzzzz";

    do
    
       scanf("%d%d", &n, &k);
       struct student
       
           char nome[21]; /*name*/
           char nomes_ordenados[21]; /*array to put the names already sorted*/
        s[n];

       for (i=0; i<n; i++)
       
           scanf(" %s", s[i].nome);
       

       for (i=0; i<n; i++)
       
           aux = strcmp(str, s[i].nome); /*compares the string that would be the last in the alphabetical order ("zzzzzzzzzzzzzzzzzzzz") with the given names*/
           if(aux>0)
           
               strcpy(str, s[i].nome); /*it gives me the name that comes first in alphabetical order */
               numMenorNome = i;  /* identification number of the name that was obtained */
           
           if (i==(n-1))
           
               strcpy(s[j].nomes_ordenados,str); 
               printf("%s\n", s[j].nomes_ordenados);
               strcpy(str, "zzzzzzzzzzzzzzzzzzzz"); 
               strcpy(s[numMenorNome].nome, str2); 
               j++;
               i=0; /* restarts the loop in order to obtain the second name in alphabetical order, the third name, the fourth name and so on */
               if(j==n)
                    break;
           
       
       printf("%s\n\n", s[k-1].nomes_ordenados);

     while (n!=0&&k!=0);
    return 0;

【问题讨论】:

scanf("%d%d", &amp;n, &amp;k); 对我来说似乎是错误的。程序如何知道n 的结尾和k 的开头在哪里?你应该有一个更一致的缩进/括号样式;否则你会让想要帮助你的人难以阅读。 您收到的两个警告是因为您需要在 C99 或更高版本 (C11) 标准下编译代码。 旁注:你可以使用qsort吗?因为这个问题要简单得多with qsort to sort the names,所以你可以直接索引找到第K个学生。您也可以跳过整个“无缘无故的具有两个不同名称的结构” schtick,只存储char* 的数组(可变长度或动态分配),对所述数组(strcmp already exists as a sort function)进行排序,然后你就在那里. @sergiol 没问题,默认情况下,大多数格式说明符会在读取值之前跳过空格,所以在它们之间放一些空格 【参考方案1】:

对字符串数组进行排序非常简单。只需使用qsort 和现有的比较功能(即strcmp

例子:

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

#define NAMES 5
#define NAME_LEN 10

void print_names(char names[][NAME_LEN])

    int i;
    for(i=0; i<NAMES; ++i)
    
        printf("%s\n", names[i]);
    


int main(void) 
    char names[NAMES][NAME_LEN] =  "xxx", "uuu", "ccc", "aaa", "bbb" ;

    print_names(names);
    printf("---------------------------------\n");

    qsort(names, NAMES, NAME_LEN, strcmp);

    print_names(names);

    return 0;

【讨论】:

【参考方案2】:

你也可以使用bubble sort算法!

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

int main(void) 
    char *names[] =  "xxx", "uuu", "ccc", "aaa", "bbb" ;
    char *tmp;
    int i = 0, j;
    for(i; names[i]; i++) 
        for(j = 0; names[j]; j++) 
            if(strcmp(names[i], names[j]) < 0) 
                tmp = names[i];
                names[i] = names[j];
                names[j] = tmp;
            
        
    
    for(i = 0; names[i]; i++) printf("%s\n", names[i]);
    return 0;

【讨论】:

以上是关于按字母顺序对字符串列表进行排序 (C)的主要内容,如果未能解决你的问题,请参考以下文章

按字母顺序对 c 字符串数组进行排序

在C ++中按非ASCII顺序的第一个字母对字符串向量进行排序

如何按字典顺序对 ArrayList 进行排序?

按字母顺序排序列表

按字母顺序对字符串数组进行排序 C++

按字符串属性C#对对象列表进行排序[重复]