问题描述
我正在学习C编程并从事学校作业。可以问老师或同伴的可能性有限(由于电晕爆发和在家疏远),我正在与您联系。非常感谢您的帮助。
我的挑战:编写一个程序,该程序使用不同的功能来对11个文本字符串进行排序,这些字符串的长度和字母顺序有关。告诉用户程序的限制是什么。
Desired output,for instance:
bc
bcb
bcebc
cbbcac
dbccac
(...)
首先,用户必须输入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]);
}
现在,我们将字符串放入“ 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;
}
我也了解,按照字母顺序排序可能看起来像这样:
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);
}
但是,我不知道如何编写比较表达式,也不了解可以保留在main函数中的哪些代码段以及合适的单独函数。一个理想的答案将包括一个示例代码,以显示如何解决此任务,因为我不但迷失了!
谢谢!
解决方法
在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;
}
输出
a
aa
ld
dcg
htj
abcd
pppp
lkjh
jkler
qwerty
zxcvbnm
如果要按长度和长度优先的字母排序,可以将比较功能更改为
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);
}
输出
a
aa
ld
dcg
htj
abcd
lkjh
pppp
jkler
qwerty
zxcvbnm
现在,输出按长度排序,并且按相等的长度将其按字母顺序排序(请注意,与以前的仅按长度排序的代码相比,“ pppp”和“ lkjh”交换了位置)。
顺便说一句:不要使用gets
来获取输入。不安全看看fgets
。