2017-01-15 73 views
-1

我是C编程的初学者,所以我的代码非常基础。它是计算字符串中字符的频率。该程序确实运行,但问题是它显示每个字符的次数,因为它出现在字符串中。所以,当我进入你好时,我会得到“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]); 
+1

'count'的定义是什么?你的代码实际上是计算完全随机的东西你不需要内部循环,但是你需要一个计数数组,其索引是'str [i]' - 字符串中第i个字符的ASCII码。 – DyZ

+0

like [this](http://ideone.com/Ns9quD) – BLUEPIXY

+2

@DYZ:完全随机并不准确 - 它被定义,但不是想要的。我同意双循环是不必要的,但你已经夸大了你的情况。对于出现两次的信件,计数将是4;对于出现三次的信,计数将是9;对于出现N次的信件,计数将是N 2。 –

回答

0

您可以使用类似

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]); 
+2

由于8位char可以取256个值(0..255或-128..127),所以使用'int frequency [256];'更常见,并且确保按值0 .555,在用'索引到数组之前,用'(unsigned char)'强制'str [i]'。 –

0

这将是一个有点难以与已编码的唯一方式打印每个字母的计数。请尝试以下方法:

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]); 
} 
+2

由于8位'char'可能需要256个值(0..255或-128..127),所以使用'int frequency [256];'更常见,并且确保按值0 ..255,用'(unsigned char)'将'str [i]'强制转换为数组索引。 –

+0

@JonathanLeffler。是。但是对于这个特殊的问题,OP只关心字母 - 大写和小写。从技术上讲,问题的范围从65(A)到122(z)是有限的。在处理之前,OP还可以对str [i]的值进行条件检查以确保它在此范围内。 – VHS

+0

这个问题没有提到'字母'。诸如'à','é','ï','ø','ü','ÿ'等字符是可以在字符串中找到的字符 - 并且如果字符串以单字节代码集编码作为8859-15,它们是无符号范围128..255中的单个字节,或者有符号范围-128 ..- 1。在123..126范围内有标点符号,在127处加上DEL;你的代码将不会处理这些。如果您检查并忽略了超出范围的值,则这或多或少都可以。程序员对输入做出不合理的假设是导致病毒和特洛伊木马以及类似攻击的原因。 –

1

我想建立自己的功能,删除重复的字符会帮助你实现你正在尝试做的。但是,没有标准函数可以帮助您从字符串中删除所有重复项。因此,请尝试构建一个函数来从字符串中删除所有重复/重复的字符并返回该字符串。这是你的功能是什么样子:

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); 

现在在双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函数中的mableced数组:

free(new_str); 

这是一个在线演示:https://ideone.com/KnkwGX