给出一个字符串,我试图计算字符串中每个字母的出现次数,然后将其频率从最高到最低排序。然后,对于出现次数相似的字母,我必须按字母顺序对其进行排序。
这种发生是成功的,但是我不知道如何向他们添加正确的字母。
我真的是C语言的初学者,您能帮我吗?
#include <stdio.h>
#include <string.h>
void main() {
printf("Enter: \n");
char sifra[10000];
int pole[26] = {0};
char pismeno, znak;
int i;
int l, max, pomm;
int m, x, y;
char abeceda[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
gets(sifra);
int n = strlen(sifra);
for (i = 0; i < n; i++) {
pismeno = tolower(sifra[i]);
if (pismeno >= 97 && pismeno <= 122) {
pole[pismeno - 97]++;
}
}
for (i = 97; i <= 122; i++) {
printf("%c --- %d -times\n", toupper(i), pole[i - 97]);
}
//sorting it here
l = 25;
do {
max = 0;
for (x = 0; x <= l; x++) {
if (pole[x] > pole[max])
max = x;
}
l--;
} while (l != 0);
for (y = 25; y > -1; y--) {
printf("%c = %d, ", toupper(122 - y), pole[y]);
}
printf(" \n ");
return 0;
}
输出应类似于Z = 15,C = 5,A = 1,B = 1 ...
答案 0 :(得分:0)
对数组进行排序时,会丢失字母的顺序。
有几种方法可以解决此问题,但是最简单的方法可能是将阵列极点转换为二维阵列。
因此将极点声明更改为:
int pole[26][2] = {0,0};
然后添加一个循环以将第二行设置为等于字母表中相应的字母。
for (i = 0; i < 26; i++) {
pole[i][1] = i;
}
这应该使数组看起来像
0,0,0,0,...,0 <---此行是出现的次数(例如,字母A出现10次)
0、1、2、3,...,25 <---此行代表值(例如0 = A,1 = B,2 = C)
现在,您可以更改排序方式以对第二列也进行排序。
do {
max = 0;
for (x = 0; x <= l; x++) {
if (pole[x][0] > pole[max][0])
max = x;
}
int tempNum = pole[l][0];
int tempLetter = pole[l][1];
pole[l][0] = pole[max][0];
pole[l][1] = pole[max][1];
pole[max][0] = tempNum;
pole[max][1] = tempLetter;
l--;
} while (l != 0);
这将对数组进行排序,因此最终看起来像这样:
15,5,1,1,...,0
25,2,0,1,...,12
(Z,C,A,B,...,M)<-这是第二行,而不是数字
您可以通过执行以下操作来获取这些值...
for (i = 0; i < 26; i++) {
printf("%c --- %d -times\n", pole[i][0], pole[i][1])
}
这是我最好的解释,希望您能理解。
答案 1 :(得分:0)
这是一种接近原始代码的可能解决方案:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXBUF 10000
int main()
{
printf("Enter: \n");
char sifra[MAXBUF];
int pole[26]={0};
char pismeno, znak;
int i;
int l, max, temp;
int m, x, y;
char abeceda[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
fgets(sifra, MAXBUF, stdin);
int n=strlen(sifra);
for(i=0; i<n; i++)
{
pismeno= tolower(sifra[i]);
if(pismeno>=97 && pismeno<=122)
{
pole[pismeno-97]++;
}
}
for(i=97; i<=122; i++)
{
printf("%c --- %d -times\n",toupper(i),pole[i-97]);
}
// Sorting it here
l= 25;
do
{
max=0;
for (x=0; x<=l; x++)
{
if (pole[x]>pole[max])
max=x;
else if (pole[x] == pole[max])
if (abeceda[x] < abeceda[max])
max = x;
}
temp=pole[l];
pole[l]=pole[max];
pole[max]=temp;
znak=abeceda[l];
abeceda[l]=abeceda[max];
abeceda[max]=znak;
l--;
}while (l!=0);
for(y=25; y>-1; y--)
{
printf("%c = %d, ",toupper(abeceda[y]), pole[y]);
}
printf(" \n ");
return 0;
}
已解决的问题和评论:
ctype.h
和tolower
的{{1}}库-尽管我认为这是一个错字。toupper
的初始化中有一个错字-它应该有26个字符而不是25个字符,并且右括号应该是方括号。请注意,您还可以编写abeceda
,编译器将自行推断出数组大小。在这种情况下,对我来说,明确地指出它似乎是一个更好的主意,因为我们正在处理的是已知大小的集合-字母。将其转换为单独的变量并在循环中重用该变量似乎是一个不错的选择。fgets
而不是char abeceda[] = {your list}
(并从他提供的link中读取帖子)-与预先定义的最大缓冲区大小{{ 1}}。gets
中的字母。MAXBUF
应该返回abeceda
而不是main()
(实际上,您返回的是int
,并且不会在我的计算机上编译)。void
(“符号”)在某种意义上可以,int
可以简单地用znak
代替。还请注意一个字母变量,例如pomm
和temp
(以及x
,y
...)-最好是更详细些或至少坚持i,j,k通常在循环中使用。如果n
之类的东西m
对我来说更具可读性。单词n
的输出现在为:
nchar
如果要删除最后一个逗号,也可以执行以下操作:
Hello
要注意的一件事是,通常情况下,您会希望使用更加模块化的设计。在这种情况下,至少要有一个用于排序而不是直接在L = 2, E = 1, H = 1, O = 1, A = 0, B = 0, C = 0, D = 0, F = 0, G = 0, I = 0, J = 0, K = 0, M = 0, N = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0,
中键入所有内容的函数。当您学习取得进步时,我建议您开始编写函数,越早越好。它们提高了程序的可读性并简化了调试。