2015-10-19 79 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