计算字符串中每个字母的出现次数

时间:2016-08-01 10:42:22

标签: c++ c

这是我的逻辑。我写了计算no的函数。字符串中每个字母的出现次数。但这不能正常工作。纠正我。

void countChar(char *str){
int i,j,cnt=1;
int l=strlen(str);
for(i=0;i<l;i++){
    for(j=i+1;j<l;j++){
            if(str[i] == str[j])
                cnt++;
    }
    printf("\n %c occurs : %d times",str[i],cnt);
    cnt=1;
}
}

如果我输入&#34;您好&#34;然后它产生输出:
h 发生:1次
e 发生:1次
l 发生:2次
l 发生:1次
o 发生:1次

预期输出:
h 发生:1次
e 发生:1次
l 发生:2次
o 发生:1次

4 个答案:

答案 0 :(得分:2)

void countChar(char *str){
    int i,j,cnt=1;
    int l;

    for(l=0; str[l]; ++l)//to low case
        str[l] = tolower(str[l]);
    for(i=0;i<l;i++){
        if(!str[i])continue;
        for(j=i+1;j<l;j++){
            if(str[i] == str[j]){
                cnt++;
                str[j] = 0;//Destructive changed so next time not to be the target
            }
        }
        printf("\n %c occurs : %d times",str[i],cnt);
        cnt=1;
    }
}

答案 1 :(得分:0)

如果我将其称为

countChar("aabbccda");

我为每个字母获得了不同的频率:

 a occurs : 3 times
 a occurs : 2 times
 b occurs : 2 times
 b occurs : 1 times
 c occurs : 2 times
 c occurs : 1 times
 d occurs : 1 times
 a occurs : 1 times

这里有一个线索:每个字母的数量减少。 您的for循环

for(j=i+1;j<l;j++)

i+1运行到字符串的末尾,因此不会回顾先前出现的给定字母。如果我们只是将该行更改为从字符串的开头再次运行:

for(j=0;j<l;j++)
//    ^------

我们越来越近了:

 a occurs : 4 times
 a occurs : 4 times
 b occurs : 3 times
 b occurs : 3 times
 c occurs : 3 times
 c occurs : 3 times
 d occurs : 2 times
 a occurs : 4 times

但是,现在我们在str[i]时将str[j]i==j进行了比较,因此请为每封信件额外计算一次。

我们可以这样说: void countChar(char * str){     int i,j,cnt = 1;     int l = strlen(str);     for(i = 0; i

给予:

a occurs : 3 times
a occurs : 3 times
b occurs : 2 times
b occurs : 2 times
c occurs : 2 times
c occurs : 2 times
d occurs : 1 times
a occurs : 3 times

现在,如果我们使用std::map来存储每个字母的计数,我们可以避免它一遍又一遍地告诉我们一封信的发生次数。

事实上,既然你把它标记为C ++,那么让我们使用基于for循环的范围和std :: cout:

void countCharImproved(char *str){
    std::map<char, int> count;
    int l = strlen(str);
    for(int i=0; i<l; i++) {
        count[str[i]]++;
    }
    for(const auto kvp : count) {
        std::cout << kvp.first << " occurs " << kvp.second << " times\n";
    }
}

给予更多的整洁:

a occurs 3 times
b occurs 2 times
c occurs 2 times
d occurs 1 times

答案 2 :(得分:0)

在我的方法中,我将所有先前匹配的字符存储在一个数组中,如果当前字符存在于数组中,则检查循环的每次迭代

#include<stdio.h>
#include<string.h>
void countChar(char *str){
 char parsed[strlen(str)]; //Array to store previously matched characters
 int flag=0; //Flag to check if currently matching character has occured before
 int i,j,cnt=1,k=0;
 int l=strlen(str);
 for(i=0;i<l;i++){

 //Check if currently matching character has occured before
 for(j=0;j<=k;j++){
if(str[i] == parsed[j]){cnt=1;flag=1;}
 }
 if(flag==1){
   flag=0;
   continue;
 }


 for(j=i+1;j<l;j++){
         if(str[i] == str[j])
             cnt++;
 }
 parsed[k++] = str[i]; //Add currently matched character to array of matched characters
 printf("\n %c occurs : %d times",str[i],cnt);
 cnt=1;
 }
}

void main(){
 countChar("Hello World");
}

答案 3 :(得分:0)

在纯C中进行分类的解决方案

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

int cmp(const void* a, const void* b)
{
    return ((*(const char*)a) - (*(const char*)b));
}

void countChar(const char *str)
{
    size_t i;
    int count = 1;
    char *sorted = strdup(str);
    size_t len = strlen(sorted);
    qsort(sorted, len, sizeof(char), cmp);

    for (i = 0; i < len; i++, count++)
    {
        if (sorted[i] != sorted[i + 1])
        {
            printf("%c occurs : %d times\n", sorted[i], count);
            count = 0;
        }
    }

    free(sorted);
}