2015-10-19 82 views
0

我的程序設計爲允許用戶輸入字符串,我的程序將輸出每個字母和單詞的出現次數。我的程序也按字母順序排列單詞。在字符串數組中排序字

我的問題是:我輸出單詞看到(第一unsorted)和他們的事件作爲表,並在我的表中,我不想重複。 求助

例如,如果單詞「to」被看到兩次,我只希望單詞「to」在我的表中只出現一次,輸出出現次數。

我該如何解決這個問題?另外,爲什麼我不能簡單地將string[i] == delim設置爲適用於每個分隔符,而不必爲每個分隔符手動分配?

編輯:修正了我的輸出錯誤。但我怎樣才能設置條件string[i]等於我的代碼中的任何分隔符,而不是僅僅爲空格鍵工作?例如,在我的輸出中,如果我輸入「你,你」,它會輸出「你,你」而不僅僅是「你」。我怎麼寫它,以便它消除逗號並將「你,你」比作一個單詞。

任何幫助表示讚賞。我的代碼如下:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
const char delim[] = ", . - !*()&^%$#@<> ? []{}\\/\""; 
#define SIZE 1000 

void occurrences(char s[], int count[]); 
void lower(char s[]); 


int main() 

{ 

    char string[SIZE], words[SIZE][SIZE], temp[SIZE]; 

    int i = 0, j = 0, k = 0, n = 0, count; 
    int c = 0, cnt[26] = { 0 }; 

    printf("Enter your input string:"); 
    fgets(string, 256, stdin); 
    string[strlen(string) - 1] = '\0'; 
    lower(string); 
    occurrences(string, cnt); 
    printf("Number of occurrences of each letter in the text: \n"); 
    for (c = 0; c < 26; c++){ 
     if (cnt[c] != 0){ 
      printf("%c \t %d\n", c + 'a', cnt[c]); 
     } 
    } 
/*extracting each and every string and copying to a different place */ 
    while (string[i] != '\0') 

    { 
     if (string[i] == ' ') 

     { 
      words[j][k] = '\0'; 
      k = 0; 
      j++; 
     } 

     else 

     { 
      words[j][k++] = string[i]; 
     } 
     i++; 
    } 

    words[j][k] = '\0'; 
    n = j; 

     printf("Unsorted Frequency:\n"); 
    for (i = 0; i < n; i++) 

    { 
     strcpy(temp, words[i]); 
     for (j = i + 1; j <= n; j++) 

     { 
      if (strcmp(words[i], words[j]) == 0) 

      { 
       for (a = j; a <= n; a++) 
        strcpy(words[a], words[a + 1]); 

       n--; 
      } 
     } //inner for 
    } 
    i = 0; 

/* find the frequency of each word */ 
    while (i <= n) { 
     count = 1; 
     if (i != n) { 
      for (j = i + 1; j <= n; j++) { 
       if (strcmp(words[i], words[j]) == 0) { 
        count++; 
       } 
      } 
     } 

     /* count - indicates the frequecy of word[i] */ 
     printf("%s\t%d\n", words[i], count); 
     /* skipping to the next word to process */ 

     i = i + count; 
    } 
    printf("ALphabetical Order:\n"); 

    for (i = 0; i < n; i++) 

    { 
     strcpy(temp, words[i]); 
     for (j = i + 1; j <= n; j++) 

     { 
      if (strcmp(words[i], words[j]) > 0) 

      { 
       strcpy(temp, words[j]); 
       strcpy(words[j], words[i]); 
       strcpy(words[i], temp); 
      } 
     } 
    } 
    i = 0; 
    while (i <= n) { 
     count = 1; 
     if (i != n) { 
      for (j = i + 1; j <= n; j++) { 
       if (strcmp(words[i], words[j]) == 0) { 
        count++; 
       } 
      } 
     } 

     printf("%s\n", words[i]); 
     i = i + count; 
    } 
    return 0; 

} 

void occurrences(char s[], int count[]){ 
    int i = 0; 
    while (s[i] != '\0'){ 
     if (s[i] >= 'a' && s[i] <= 'z') 
      count[s[i] - 'a']++; 
     i++; 
    } 
} 

void lower(char s[]){ 
    int i = 0; 
    while (s[i] != '\0'){ 
     if (s[i] >= 'A' && s[i] <= 'Z'){ 
      s[i] = (s[i] - 'A') + 'a'; 
     } 
     i++; 
    } 
} 
+0

您似乎誤解了一些語法,或者犯了一個簡單的錯誤:)'words [i] == NULL;'不做任何聲明。你將'words'中的'i'與'NULL'進行比較,'=='是相等運算符。該聲明甚至可能被編譯器優化掉。它在語法上有效,但什麼都不做,因爲你不會對結果做任何事情。沒有看過代碼的其餘部分,但你很可能希望'='(賦值) – Skurmedel

+0

lower()被破壞:用_s [i] =(s [s]替換_s [i] = s [i] + 32_我] - 'A')+'a'_ –

+0

謝謝我修復了Craig。 – Benny

回答

0

我有解決您的問題,其名稱爲Wall。不,當你遇到一個你看起來無法解決的問題時,而不是你想要的編譯器發出的警告,而不是你的頭。

如果您使用-Wall編譯出C代碼,那麼您可以提交所有人告訴您的錯誤是爲什麼C非常危險。但是一旦啓用警告,編譯器會告訴你有關它們的信息。

我有4個爲你的程序:

for (c; c< 26; c++) {,首先C沒有做任何事情,這可以寫成for (; c < 26; c++) {或者是尤爲明顯的for (c = 0; c <26; c++) {

words[i] == NULL「有沒有效果聲明」。那麼這可能不是你想要做的。編譯器告訴你那行不做任何事情。

「未使用的變量文本」。「這也很明顯:你已經將文本定義爲一個變量,但從未使用它。也許你的意思是或者它可能是你認爲需要的變量。無論哪種方式,它現在可以走了。

「控制達到非無效功能的結束」。在C main中通常定義爲int main,即main返回一個int。標準做法是如果程序成功完成並返回一些其他錯誤值,則返回0。在主結束時添加return 0;將工作。

+0

謝謝我進行了這些修改以避免警告出現。我的原始問題仍然是思想。 – Benny

0

您可以簡化您的分隔符。任何是而不是 a-z(在下殼後),是一個分隔符。你不需要關心它是哪一個。這是一個詞的結尾。而不是指定分隔符,請指定字符的字符(例如,如果單詞是C符號,則單詞chars將爲:A-Z,a-z,0-9和_)。但是,看起來你只想要a-z。

這裏有一些[未測試例:

void 
scanline(char *buf) 
{ 
    int chr; 
    char *lhs; 
    char *rhs; 
    char tmp[5000]; 

    lhs = tmp; 

    for (rhs = buf; *rhs != 0; ++rhs) { 
     chr = *rhs; 

     if ((chr >= 'A') && (chr <= 'Z')) 
      chr = (chr - 'A') + 'a'; 

     if ((chr >= 'a') && (chr <= 'z')) { 
      *lhs++ = chr; 
      char_histogram[chr] += 1; 
      continue; 
     } 

     *lhs = 0; 
     if (lhs > tmp) 
      count_string(tmp); 

     lhs = tmp; 
    } 

    if (lhs > tmp) { 
     *lhs = 0; 
     count_string(tmp); 
    } 
} 

void 
count_string(char *str) 
{ 
    int idx; 
    int match; 

    match = -1; 
    for (idx = 0; idx < word_count; ++idx) { 
     if (strcmp(words[idx],str) == 0) { 
      match = idx; 
      break; 
     } 
    } 

    if (match < 0) { 
     match = word_count++; 
     strcpy(words[match],str); 
    } 

    word_histogram[match] += 1; 
} 

使用單獨的陣列是難看。使用結構可能會更好:

#define STRMAX  100  // max string length 
#define WORDMAX  1000  // max number of strings 

struct word { 
    int word_hist;    // histogram value 
    char word_string[STRMAX]; // string value 
}; 

int word_count;     // number of elements in wordlist 
struct word wordlist[WORDMAX]; // list of known words