【问题标题】:Unique Words Counter in CC中的唯一单词计数器
【发布时间】:2017-05-30 13:07:20
【问题描述】:

我正在用 C 编写一个小程序,它应该计算 c 中的唯一单词。 为此,我有一个单词本来存储所有找到的单词。通常,它应该只将尚未包含在其中的单词放入其中,但它会不断输入所有已写入的单词。 我该如何解决这个问题以及如何删除我的单词本“woerterbuch”中的所有空白部分?

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


char lies_wort(char *Text);
char suche_wort(char *wort);
char neues_wort(char *wort);
char *woerterbuch[1000];

int main(void)
{
    char Text[1000];
    printf("Bitte Text eingeben : \n") ;
    fgets (Text, 1000, stdin);
    lies_wort(Text);
    int i;
    for(i=0;i<1000;i++){
        printf("woerterbuch :%s\n",woerterbuch[i]);}
}
char lies_wort(char *Text){
    char *wort;
    int i=1;
    wort = strtok(Text, " ,.!?;:");
    while(wort != NULL) {
        suche_wort(wort);
        printf("gefunden %d: %s\n", i++, wort);
        wort = strtok(NULL, " ,.!?;:");}
}
char suche_wort(char *wort)
{
    int i;
    for (i = 0; i>1000; i++){
        if (!strcmp(woerterbuch[i],wort)){return 0;}}
    neues_wort(wort);
    return 0;
}
char neues_wort(char *wort)
{
    int i;
    for (i=0; i<1000; i++){
        if(woerterbuch[i]==0){
            woerterbuch[i]=wort;
            return 0;}}
}

为了测试这个程序只是打印“woerterbuch”中的所有单词,所以我可以检查它是否工作。

【问题讨论】:

  • suche_wort 中使用空指针。好吧,如果循环确实有效,您会...仔细看看那里的循环条件。
  • 哪个是空指针?
  • 请记住,全局变量将被“零初始化”,这意味着指针(如woerterbuch 数组中的指针)将为空。并且您使用woerterbuch 中的指针 中初始化neues_wort 中的这些指针。
  • 啊,谢谢我试试
  • woerterbuch[i]=wort; --> woerterbuch[i]=strdup(wort);

标签: c unique counting words


【解决方案1】:

suche_wort

for (i = 0; i>1000; i++)

应该是

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

您的循环每次都会立即终止。

【讨论】:

  • 您应该存储 woerterbuch 的当前大小。并且只搜索那个大小而不是全部 1000,因为它们中的大多数都是 NULL。对于 (i = 0; i
【解决方案2】:

我相信您的代码中存在一些问题:

首先,在这一行:

woerterbuch[i]=wort;

只会覆盖woerterbuch[i]的地址,这会导致错误的结果。相反,您需要通过mallocstrdupworterbuch[i] 分配空间。

您可以像这样为单个指针分配空间:

worterbuch[i] = malloc(strlen(wort)+1);

注意:最后检查malloc()free()这些指针的返回总是好的。

现在,由于指针指向某个地方,您可以将内容复制到其中。您可以使用strcpy 来执行此操作。如果您想跳过此复制步骤,您可以使用 strdup() 代替。

其次,您可以在struct 中管理这个指针数组,而不是全局定义char *woerterbuch[1000];

typedef struct {
    char *woerterbuch[1000];
    size_t n;
} worterbuch;

这样可以更轻松地管理您的阵列。

第三,你没有检查fgets()的返回。如果不成功,这可以返回NULL。您还应该在此处检查缓冲区溢出。

最后,如果您的worterbuch 中有很多单词,则使用线性搜索检查重复项可能效率不高。这个过程平均需要 O(N) 时间。相反,您可以使用二分查找,平均时间 O(logN),因此如果 n 变得非常大,效率会更高。

这是我不久前写的一些代码,它做了类似的事情:

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

#define TEXTSIZE 1000

typedef struct {
    char *dictionary[TEXTSIZE];
    size_t numwords;
} dictionary_t;

void read_text(char *text);
void read_words(char *text, dictionary_t *dict);
int search_word(dictionary_t *dict, char *word);
void print_words(dictionary_t *dict);
int str_cmp(const void *a, const void *b);

int main(void) {
    dictionary_t dict;
    char text[TEXTSIZE];

    read_text(text);

    read_words(text, &dict);

    print_words(&dict);

    return 0;
}

void read_text(char *text) {
    size_t slen;

    printf("Please enter text: \n");
    if (fgets(text, TEXTSIZE, stdin) == NULL) {
        fprintf(stderr, "Error reading text\n");
        exit(EXIT_FAILURE);
    }

    /* removes '\n' character from fgets(), and checks for overflow */
    slen = strlen(text);
    if (slen > 0) {
        if (text[slen-1] == '\n') {
            text[slen-1] = '\0';
        } else {
            printf("Buffer overflow detected.\n");
            exit(EXIT_FAILURE);
        }
    }

    if (!*text) {
        printf("No text entered.\n");
        exit(EXIT_FAILURE);
    }
}

void read_words(char *text, dictionary_t *dict) {
    char *word;
    const char *delim = " ,.!?;:";
    dict->numwords = 0;

    word = strtok(text, delim);
    while (word != NULL) {

        if (search_word(dict, word)) {

            /* allocate space for ptr */
            dict->dictionary[dict->numwords] = malloc(strlen(word)+1);
            if (!dict->dictionary[dict->numwords]) {
                printf("Cannot allocate word.\n");
                exit(EXIT_FAILURE);
            }

            /* copy it into array */
            strcpy(dict->dictionary[dict->numwords], word);

            /* increment count, ready for next word */
            dict->numwords++;
        }
        word = strtok(NULL, delim);
    }
}

/* linear searching the word */
int search_word(dictionary_t *dict, char *word) {
    size_t i;

    for (i = 0; i < dict->numwords; i++) {
        if (strcmp(dict->dictionary[i], word) == 0) {
            return 0;
        }
    }
    return 1;
}

/* cmp function for sorting dictionary */
int str_cmp(const void *a, const void *b) {
    const char **str1 = (const char **)a;
    const char **str2 = (const char **)b;

    return strcmp(*str1, *str2);
}

void print_words(dictionary_t *dict) {
    size_t i;

    /* sort using qsort */
    qsort(dict->dictionary, dict->numwords, sizeof(*(dict->dictionary)), str_cmp);

    printf("\nDictionary:\n");
    for (i = 0; i < dict->numwords; i++) {
        printf("%s\n", dict->dictionary[i]);

        /* freeing memory previosly allocated from malloc() */
        free(dict->dictionary[i]);
        dict->dictionary[i] = NULL;
    }
}

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    相关资源
    最近更新 更多