2017-01-15 90 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