如何按 1) 长度和 2) 字母顺序对 char 数组进行排序?

swe*_*ent 1 c arrays sorting string-length alphabetical-sort

我正在学习 C 编程并正在完成学校作业。由于向老师或同学询问的可能性有限(由于新冠病毒爆发和在家中保持距离),我正在与您联系。非常感谢您的帮助。

我的挑战:编写一个程序,使用不同的函数对 11 个文本字符串按照长度和字母顺序进行排序。告诉用户该程序的限制是什么。

Desired output, for instance:
bc
bcb
bcebc
cbbcac
dbccac
(...)
Run Code Online (Sandbox Code Playgroud)

首先,用户必须输入 11 个文本字符串。我已经用以下代码解决了这个问题:

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

#define NUMBER_OF_STRINGS 11


int main (void)

char textstrings[NUMBER_OF_STRINGS][15];
int i;

(...) 

printf("Enter 11 textstrings, one by one:\n");
for(i=0;i<NUMBER_OF_STRINGS-1;i++)
   {
   printf("Enter string %d: ", i + 1);
   gets(textstrings[i]);
   }
Run Code Online (Sandbox Code Playgroud)

现在我们在“textstrings[i]”中得到了字符串,必须对它们进行排序并打印。我认为最好看的方法是为每个排序条件提供单独的函数。例如,一个单独的函数用于“长度”,然后另一个函数用于“字母顺序”。我知道我应该使用“strlen”来比较长度,使用“strcmp”来比较字母顺序。

我还了解按多个条件排序的策略是为每个返回比较函数的适当返回类型的条件编写比较表达式,并按所需的排序顺序(例如,首先是长度,然后是字母顺序)对它们进行评估。

这就是我迷失的地方......

但是,我确实理解按长度排序的逻辑可能如下所示:

char* temp;
int step
int length=20; //Not allowing text longer than 20 characters.

for(step=0;step<length-1;step++)
for(i=0;i<length-step-1;i++)
  {
  if(strlen(textstrings[i])>strlen(textstrings[i+1]))
   {
   temp=textstrings[i];
   textstrings[i]=textstrings[i+1];
   textstrings[i+1]=temp;
   }
Run Code Online (Sandbox Code Playgroud)

我还了解到,按照字母顺序排序可能看起来像这样:

int k, m

for(k=0;k<=NUMBER_OF_STRINGS-1;k++)
{
  for(m=k+1;m<=NUMBER_OF_STRINGS-1;m++)
     if(strmcp(textstrings[k], textstrings[m])>0)
     swap(textstrings[k], textstrings[m]);
}

       where a swap function would look like:

      void swap (char *s1, char *s2)
      {
      char tmp[20];
      strcopy(temp,s1);
      strcopy(s1,s2);
      strcopy(s2,temp);
      }
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何编写比较表达式,也不明白哪些代码可以保留在主函数中,以及哪些单独的函数是合适的。理想的答案将包括一个示例代码来展示如何解决此任务,因为我完全迷失了!

谢谢你!

438*_*427 5

当在 C 中对数组进行排序时,你的朋友是qsort. 您需要实现的只是一个比较函数,然后调用qsort

例如:

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

#define NUMBER_OF_STRINGS 11

int cmplen(const void *p1, const void *p2)
{
    size_t len1 = strlen((const char *) p1);
    size_t len2 = strlen((const char *) p2);
    if (len1 < len2) return -1;
    if (len1 > len2) return  1;
    return 0;
}

int main(int argc, char const *argv[])
{
    char textstrings[NUMBER_OF_STRINGS][15] = {"abcd", "dcg", "htj", "jkler", "qwerty", "zxcvbnm", "a", "aa", "pppp", "lkjh", "ld"};
    qsort(textstrings, NUMBER_OF_STRINGS, sizeof textstrings[0], cmplen);
    for (size_t i = 0; i < NUMBER_OF_STRINGS; ++i) puts(textstrings[i]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出

a
aa
ld
dcg
htj
abcd
pppp
lkjh
jkler
qwerty
zxcvbnm
Run Code Online (Sandbox Code Playgroud)

如果您想同时按长度和字母排序,其中长度具有最高优先级,您可以将比较函数更改为

int cmplen(const void *p1, const void *p2)
{
    size_t len1 = strlen((const char *) p1);
    size_t len2 = strlen((const char *) p2);
    if (len1 < len2) return -1;
    if (len1 > len2) return  1;
    return strcmp((const char *) p1, (const char *) p2);
}
Run Code Online (Sandbox Code Playgroud)

输出

a
aa
ld
dcg
htj
abcd
lkjh
pppp
jkler
qwerty
zxcvbnm
Run Code Online (Sandbox Code Playgroud)

现在输出按长度排序,并且对于相同长度,它按字母顺序排序(请注意,与仅按长度排序的先前代码相比,“pppp”和“lkjh”交换了位置)。

顺便说一句:不要用于gets获取输入。这是不安全的。而是看一下fgets