我的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);
}
答案 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