C 如何计算字符串中字符的频率

C 如何计算字符串中字符的频率,c,arrays,frequency,C,Arrays,Frequency,我是C编程的初学者,所以我的代码非常基础。它是计算字符串中字符的频率。该程序确实在运行,但问题是它显示每个字符的次数与它在字符串中出现的次数相同。所以,当我输入hello时,我得到“h出现1次,e出现1次,l出现2次,l出现2次,o出现1次”。我如何消除这一点,使我的计数只出现一次 for(i=0;str[i]!='\0';i++) { for(j=0;str[j]!='\0';j++) { if(str[i]==str[j])

我是C编程的初学者,所以我的代码非常基础。它是计算字符串中字符的频率。该程序确实在运行,但问题是它显示每个字符的次数与它在字符串中出现的次数相同。所以,当我输入hello时,我得到“h出现1次,e出现1次,l出现2次,l出现2次,o出现1次”。我如何消除这一点,使我的计数只出现一次

for(i=0;str[i]!='\0';i++)
{
  for(j=0;str[j]!='\0';j++)
        {
            if(str[i]==str[j])
                    count[i]++;
        }
}
for(i=0;i<str[i]!='\0';i++)
    printf("%c occurs %d times \n",str[i],count[i]);
for(i=0;str[i]!='\0';i++)
{
对于(j=0;str[j]!='\0';j++)
{
if(str[i]==str[j])
计数[i]++;
}
}

对于(i=0;i您可以使用

int characters[128] = {0};
char string[] = "Hello, World!";
for(int i = 0; string[i] != '\0'; i++) 
    characters[(int)string[i]]++;

for(int i = 0; i < 128; i++) 
    if(characters[i] != 0) 
        printf("%c occurs %d times\n", (char)i, characters[i]);
int字符[128]={0};
char string[]=“你好,世界!”;
for(int i=0;字符串[i]!='\0';i++)
字符[(int)字符串[i]]++;
对于(int i=0;i<128;i++)
如果(字符[i]!=0)
printf(“%c出现%d次\n”,(字符)i,字符[i]);

用编码的方式唯一地打印每个字母的计数会有点困难。请尝试以下方法:

int frequency[122] = {0}; //ascii value of z is 122.
for(i=0;str[i]!='\0';i++)
{
    frequency[str[i]]++;
}
for(i=0;i<=122;i++) {
    if(frequency[i] != 0)
        printf("%c occurs %d times\n", str[i], count[i]);
}
int frequency[122]={0};//z的ascii值为122。
对于(i=0;str[i]!='\0';i++)
{
频率[str[i]]++;
}

对于(i=0;i我认为构建自己的函数来删除重复的字符将有助于实现您正在尝试的操作。但是,没有标准函数可以帮助您删除字符串中的所有重复字符。因此,请尝试构建一个函数来删除字符串中的所有重复字符,并返回string。以下是您的函数的外观:

char* remove_duplicated(char* str, int size) {
    int frequency[256] = {0};
    char* new_str = malloc(size);
    int new_size = 0;

    for(int i=0; str[i]!='\0'; i++)
    {
        if(frequency[(unsigned char) str[i]] == 0) {
            frequency[(unsigned char) str[i]]++;
            new_str[new_size] = str[i];
            new_size++;
        }
    }

    new_str[new_size] = '\0';

    return new_str;
}
构建上述函数后,发送要测量字符频率的字符串,并存储返回的字符串。如下所示:

char* new_str = remove_duplicated(str, size);
现在,在您正在使用的double
for
循环中,将
new_str
用于外部for循环,并将其用于
for
循环显示
count

for(i=0; new_str[i]!='\0'; i++)
{
    for(j=0; str[j]!='\0'; j++)
    {
        if(new_str[i] == str[j])
            count[i]++;
    }
 }
 for(i=0; new_str[i]!='\0'; i++)
     printf("%c occurs %d times \n", new_str[i], count[i]);
不要忘记在remove_duplicated函数中释放malloced数组:

free(new_str);

这里有一个在线演示:

计数的定义是什么?你的代码实际上是计算一些完全随机的东西。你不需要内部循环,但你需要一个计数数组,其中索引是
str[i]
-字符串中
i
第个字符的ASCII码。比如@DYZ:完全随机是不准确的-它是定义的,但不是需要的。我同意双循环是不必要的,但您已经过度陈述了您的情况。对于出现两次的字母,计数将为4;对于出现三次的字母,计数将为9;f或者一个出现N次的字母,计数将是N²。@JonathanLeffler所说的“完全随机”实际上是指“不需要”但你是对的,它确实计算了频率的平方!我选择的副本的答案计算了字符串中每个字符的频率,然后建议通过频率表进行线性扫描以找到最小和最大频率。你可以进行线性扫描并打印非零频率。还有是相关的,尽管问题已经结束。由于8位
字符可以接受256个值(0..255或-128..127),因此更常用的方法是使用
int frequency[256];
并确保按值0..255进行索引,使用
(无符号字符)强制转换
str[i]
在使用它索引到数组中之前。@JonathanLeffler。是的。但是对于这个特殊的问题,OP只涉及字母表-大写和小写。所以从技术上讲,问题的范围限制在65(A)到122(z)。OP还可以对str[i]的值进行条件检查在处理它之前确保它在这个范围内。问题没有提到“字母表”。诸如“a”、“é”、“ï”、“ø”、“ü”、“ÿ”之类的字符是可以在字符串中找到的字符-如果字符串是以单字节码集(如8859-15)编码的,则它们是无符号范围128..255或有符号范围-128.中的单字节。。-1.标点符号的范围为123..126,加上127处的DEL;您的代码无法处理这些标点符号。如果您检查并忽略超出范围的值,这或多或少是正常的。程序员对输入做出不必要的假设会导致病毒、特洛伊木马和类似的攻击。同意。但是,OP总是可以将在处理str[i]之前,对其值进行条件检查,以确保其在该范围内。由于8位
char
可以接受256个值(0..255或-128..127),因此更常用的方法是使用
int frequency[256];
并确保按值0..255进行索引,使用
强制转换
str[i]
(无符号字符)
然后使用它索引到数组中。