2016-09-30 11 views
0

私はC言語を学んでいて、いくつかの苦労があります。プログラムを作成しなければなりません。これはテキスト(最大80文字)すべての単語がint count []内のテキストに含まれている回数(各単語はこの配列内で1回だけでなければならず、グローバルとしても定義されています)単語[] []からこれと同じでなければなりません)。 この関数は、int extract_and_count(char * source、int * count)と呼ばれます。 私はいくつかのコードを書いていますが、この関数をどのように正確に実装するかはわかりません。 私はstackoverflowにも新しくなっていますので、間違いがあれば、ごめんなさい。テキスト(文字の配列)から単語を抽出し、2次元配列に配置する関数

コードの一部ザッツ

が、その終わりではないに:ない「一度だけ、各単語」のあなたの要件ごとに、分割さ的にすべての単語が含まれています

int extract_and_count(char *source,int *count){ 
    char token[80][80]; 
    char *p; 
    int i = 0; 
    p = strtok(source, " "); 
    while(p != NULL){ 
    strcpy(token[i],p); 
    printf("%s\n",*(token+i)); 
    i++; 
    p = strtok(NULL , " "); 
    } 
    char word; 
    int value = 0, j; 
    for(i = 0 ; i < 80 ; i++){ 
    word = token[i]; 
    for(j = 0 ; j < 80 ; j++){ 
     if(strcmp(word,token[i])==0){ 
    value++; 
     } 
    } 

    } 
    return 1; 
} 
+1

ここにコード – GMichael

+1

を投稿してください私は、問題のいくつかのコードを入れて、それは良いものではなく、まったく動作しません。ちょうどスタートバージョンです。私はすべての単語を格納するために新しい配列を作成し、次にトークン[] []内の単語の値を数え、単語[] [] count []内の値。 –

+0

私はまだあなたの目的を理解していません。また、「extract_and_count」の入力パラメータの意味、単語区切りの意味、配列内の単語の並び方を理解していません – GMichael

答えて

0

単語が見つかったかどうかを確認する必要があります。その場合は、グローバルカウンタをインクリメントします。それ以外の場合は、新しい単語を文字列のグローバル配列にコピーします。

のような何か:

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

// Global variables to hold the results 
char word[80][81]; 
int count[80] = { 0 }; 

int extract_and_count(char *source,int *strings_cnt){ 
    char token[80][81]; 
    char *p; 
    int i = 0; 

    // Find all words in the input string 
    p = strtok(source, " "); 
    while(p != NULL){ 
    strcpy(token[i],p); 
    // printf("%s\n",*(token+i)); 
    i++; 
    p = strtok(NULL , " "); 
    } 

    // Find unique words and count the number a word is repeated 
    *strings_cnt = 0; 
    int j,k; 

    // Iterator over all words found in the input string 
    for(j = 0 ; j < i ; j++){ 

    // Check if the word is already detected once 
    int found = 0; 
    for(k = 0 ; k < *strings_cnt ; k++){ 
     if (strcmp(word[k], token[j]) == 0) 
     { 
     // The word already exists - increment count 
     found = 1; 
     count[k]++; 
     break; 
     } 
    } 

    if (!found) 
    { 
     // New word - copy it and set count to 1 
     strcpy(word[*strings_cnt], token[j]); 
     count[*strings_cnt] = 1; 
     (*strings_cnt)++; 
    } 
    } 

    return 1; 
} 

int main(void) 
{ 
    char s[] = "c language is difficult c is also fun"; 
    int c, i; 

    printf("Searching: %s\n", s); 

    extract_and_count(s, &c); 

    printf("Found %d different words\n", c); 
    for (i=0; i<c; i++) 
    { 
    printf("%d times: %s\n", count[i], word[i]); 
    } 
    return 0; 
} 

出力:

Searching: c language is difficult c is also fun 
Found 6 different words 
2 times: c 
1 times: language 
2 times: is 
1 times: difficult 
1 times: also 
1 times: fun 

私はあなたのコードのスタイルに従うことを試みたが、私はこれらのコメントを追加したいと上:

1)あなた実際には配列tokenは必要ありません。最初のループは、最終結果を直接更新するように変更することができます。

2)は、コードのような通常のセパレータを扱うことができない)

3グローバル変数を使用しないでください。 :など

4)単語とカウントを構造体に入れる必要があります。

コメント1,2および考慮に4を考慮すると、コードは次のようになります。

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

// Global variables to hold the results 
struct WordStat 
{ 
    char word[81]; 
    int count; 
}; 


int extract_and_count(char *source,int *strings_cnt, struct WordStat* ws, int max){ 
    char *p; 
    int i = 0; 
    int k; 
    *strings_cnt = 0; 

    // Find all words in the input string 
    p = strtok(source, " "); 
    while(p != NULL){ 
    // Check if the word is already detected once 
    int found = 0; 
    for(k = 0 ; k < *strings_cnt ; k++){ 
     if (strcmp(ws[k].word, p) == 0) 
     { 
     // The word already exists - increment count 
     found = 1; 
     ws[k].count++; 
     break; 
     } 
    } 

    if (!found) 
    { 
     // New word - copy it and set count to 1 
     strcpy(ws[*strings_cnt].word, p); 
     ws[*strings_cnt].count = 1; 
     (*strings_cnt)++; 
    } 

    i++; 
    p = strtok(NULL , " "); 
    } 

    return 1; 
} 

#define MAX_WORDS 80 

int main(void) 
{ 
    struct WordStat ws[MAX_WORDS]; 
    char s[] = "c language is difficult c is also fun"; 
    int c, i; 

    printf("Searching: %s\n", s); 

    extract_and_count(s, &c, ws, MAX_WORDS); 

    printf("Found %d different words\n", c); 
    for (i=0; i<c; i++) 
    { 
    printf("%d times: %s\n", ws[i].count, ws[i].word); 
    } 
    return 0; 
} 
+0

ありがとう!それはまさに私が望んでいたものです。 –

+0

私はコードがプロトタイプint extract_and_count(char * source、int * count)のようになりたいと思います ソースはchar []で、countは任意の単語の繰り返しのint配列です –

0
while(p != NULL){ 
    strcpy(token[i],p); 
    printf("%s\n",*(token+i)); 
    i++; 
    p = strtok(NULL , " "); --> here you are just splitting the words 
    } 

今すぐトークン。ユニークな単語を比較して別の配列にコピーすることができます。同じループでカウント配列をカウントして更新できます。

注:全体で1つのカウンタ変数を使用しないでください。カウンタの配列は、その語数をカウントするためにのみ使用されます。

0
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

#define NUM_OF_WORDS_MAX 80 
#define MAX_WORD_LENGTH 79 
#define S_(x) #x 
#define S(x) S_(x) //number literal convert to string 

char words[NUM_OF_WORDS_MAX][MAX_WORD_LENGTH+1]; 
int Words_entry = 0; 

static inline int hash(const char *str){ 
    return (tolower(*str) - 'a')*3;//3:(NUM_OF_WORDS_MAX/26), 26 : a-z 
} 

char *extract(char **sp){//extract word 
    char *p = *sp; 
    while(*p && !isalpha(*p))//skip not alpha 
     ++p; 
    if(!*p) 
     return NULL; 
    char *ret = p;//first word 
    while(*p && isalpha(*p))//skip alpha 
     ++p;//*p = tolower(*p); 
    if(!*p){ 
     *sp = p; 
    } else { 
     *p = '\0'; 
     *sp = ++p;//rest 
    } 

    return ret; 
} 

int extract_and_count(char *source, int *count){ 
    char *sp = source; 
    char *word; 
    int word_count = 0; 

    while(word = extract(&sp)){ 
     if(Words_entry == NUM_OF_WORDS_MAX){ 
      fprintf(stderr, "words table is full.\n"); 
      return word_count; 
     } 

     int index = hash(word); 
     while(1){ 
      if(*words[index]){ 
       if(strcasecmp(words[index], word) == 0){//ignore case 
        ++count[index]; 
        break; 
       } 
       if(++index == NUM_OF_WORDS_MAX){ 
        index = 0; 
       } 
      } else { 
       strcpy(words[index], word); 
       count[index] = 1; 
       ++Words_entry; 
       break; 
      } 
     } 
     ++word_count; 
    } 
    return word_count; 
} 

int main(void){ 
    int count[NUM_OF_WORDS_MAX] = {0}; 
    char text[MAX_WORD_LENGTH+1]; 

    while(1==scanf("%" S(MAX_WORD_LENGTH) "[^\n]%*c", text)){//end if only enter press. 
     extract_and_count(text, count); 
    } 
    //print result 
    for(int i = 0; i < NUM_OF_WORDS_MAX; ++i){ 
     if(*words[i]){ 
      printf("%s : %d\n", words[i], count[i]); 
     } 
    } 
    return 0; 
} 
関連する問題