区分单词中的单词

时间:2016-12-22 12:33:56

标签: c cs50

我的trie中有一个单词“all”,单词“alter”但是“alt”不是trie中的单词。但是当我检查“alt”时它仍然返回true,因为is_word为真,因为“all”是一个单词。应该如何处理这个错误。

public JsonResult FetchP(string O)
{
    List<SelectListItem> PList = new List<SelectListItem>();
     PList = _PService.GetAllPActive()
              .Select(i => new SelectListItem()
                         {
                             Text = i.PName,
                             Value = i.PID                                   
                         }).ToList();

    return Json(PList, JsonRequestBehavior.AllowGet);
}

1 个答案:

答案 0 :(得分:1)

您需要确保新节点中的所有指针都为空,并将is_word值设置为false。通过使用calloc()来分配空间,这可能是最容易完成的。创建一个分配和错误检查节点分配的功能使其更容易。同样,您有两个代码块将字符映射到trie索引。你应该更慷慨地使用函数 - 甚至是小函数。

一行数据的逐个字符输入也不是必需的;最好使用fgets()来读取行。

添加这些和其他各种更改(例如,本地数组word而不是动态分配的数组 - 没有被释放;完成后关闭文件;等等)给出MCVE({{3像这样:

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

enum { LENGTH = 256 };

// Here's the code
typedef struct node
{
    bool is_word;
    struct node *children[27];
} node;

unsigned int wsize = 0;
node *root;

static inline int map_char(unsigned char c)
{
    int t;
    if (isalpha(c))
        t = tolower(c) - 'a';
    else
        t = 26;
    return t;
}

static inline node *alloc_node(void)
{
    node *new_node = calloc(1, sizeof(node));
    if (new_node == 0)
    {
        fprintf(stderr, "Memory allocation failed in %s\n", __func__);
        exit(1);
    }
    return new_node;
}

static bool check(const char *word)
{
    node *chrawler = root;
    int len = strlen(word);
    for (int i = 0; i < len; i++)
    {
        int t = map_char(word[i]);
        if (chrawler->children[t] == NULL)
            return false;
        else
            chrawler = chrawler->children[t];
    }

    return chrawler->is_word;
}

// Load function
static bool load(const char *dictionary)
{
    FILE *inptr = fopen(dictionary, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Failed to open file '%s' for reading\n", dictionary);
        return false;
    }

    root = alloc_node();

    char word[LENGTH];
    while (fgets(word, sizeof(word), inptr) != 0)
    {
        word[strcspn(word, "\n")] = '\0';
        printf("[%s]\n", word);
        node *chrawler = root;
        int len = strlen(word);
        for (int i = 0; i < len; i++)
        {
            int t = map_char(word[i]);
            //printf("t = %d (%c)\n", t, word[i]);
            if (chrawler->children[t] == NULL)
                chrawler->children[t] = alloc_node();
            chrawler = chrawler->children[t];
        }
        chrawler->is_word = 1;
        wsize++;
    }
    printf("%d words read from %s\n", wsize, dictionary);
    fclose(inptr);

    return true;
}

int main(void)
{
    const char *wordfile = "words.txt";
    if (load(wordfile))
    {
        char line[4096];
        while (fgets(line, sizeof(line), stdin) != 0)
        {
            line[strcspn(line, "\n")] = '\0';
            if (check(line))
                printf("[%s] is a word\n", line);
            else
                printf("[%s] is unknown\n", line);
        }
    }
    return 0;
}

应该进行其他更改。例如, wsize变量应该是非全局的;它并不是在load()函数之外使用的。很容易争辩说,根节点也不应该是全局的; load()函数应该返回根节点,check()函数应该通过根节点。通常,应尽可能避免全局变量,并且通常是可能的。

给定文件words.txt包含:

abelone
abyssinia
archimedes
brachiosaurus
triceratops
all
alter
asparagus
watchamacallit
a
abracadabra
abyss
ant

程序运行的输出是:

[abelone]
[abyssinia]
[archimedes]
[brachiosaurus]
[triceratops]
[all]
[alter]
[asparagus]
[watchamacallit]
[a]
[abracadabra]
[abyss]
[ant]
13 words read from words.txt
a
[a] is a word
ab
[ab] is unknown
al
[al] is unknown
all
[all] is a word
alt
[alt] is unknown
alte
[alte] is unknown
alter
[alter] is a word
triceratops
[triceratops] is a word
brachiosaurus
[brachiosaurus] is a word
abys
[abys] is unknown
abbey
[abbey] is unknown
abyss
[abyss] is a word
ant
[ant] is a word
a
[a] is a word
archimedes
[archimedes] is a word