2016-09-30 3 views
0

Я изучаю C и немного борюсь. Мне нужно создать программу, которая станет текстом (макс. 80 символов) и поставить слова из текста в словах char [80] [80] (каждое слово должно быть только однократно в этом массиве, оно также определяется как глобальное) и количество раз, когда каждое слово входит в текст в int count [] (Index должен быть таким же, как это из слов [] []). Функция называется 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 
    } 

Теперь маркер будет содержать все слова в расщепленной форме, а не в соответствии с вашим требованием «каждое слово только один раз». Вы можете сравнивать и копировать уникальные слова в другой массив и в том же цикле, вы можете подсчитать и обновить массив count.

Примечание: Вы не должны использовать одну переменную счетчика в целом, массив счетчиков должен использоваться только для подсчета слов.

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; 
} 
Смежные вопросы