【问题标题】:Trie Implementation Logic Errors?尝试实现逻辑错误?
【发布时间】:2017-11-03 04:52:10
【问题描述】:

我目前正在研究一个 trie 实现:

  1. 从文本文件中读取一个单词
  2. 逐个字符迭代该单词
  3. 将该字符的字母索引编号附加到新节点并将其附加到根节点

我在第 3 步遇到问题。

你看,我在第三步要做的是:

  1. 如果需要,则创建一个新节点(如果需要的节点已经存在,请跳过第 2 步)
  2. 将该新节点附加到 root 的 children 数组,在该数组中附加到扫描字符的字母索引位置 例如如果要扫描“a”,则新节点将附加到 root->children[a 的字母索引
  3. 移动到根中的下一个节点,以便下一个节点将附加到该节点

为了进一步缩小问题范围,我仍在尝试解决第二、第三和第四个问题。

对于第二步,到目前为止我尝试的是:

if(root->children[index] == NULL) root->children[index] = makeNewNode();

假设 rootindex 已经定义,makeNewNode() 将新节点初始化为 NULL

第三步,我已经完成了:

root = root->children[index];

设置 root 使其成为下一个节点

我是否在这些陈述中犯了任何逻辑错误?

trie 节点结构和根声明

typedef struct trieNode
{
    bool endOfWord;
    // 27 not 26 because an apostrophe also counts as a character
    struct trieNode *children[27];

} trieNode;

//Make a new node function prototype.
trieNode* makeNewNode();

trieNode *root;

加载函数

bool load(const char *dictionary)
{
    // open dictionary file
    FILE *file = fopen(dictionary, "r");

    // check if file opened successfully
    if(file == NULL)
    {
        fprintf(stderr, "Can't open file.\n");
        unload();
        return false;
    }

    // initialize root
    root = makeNewNode();

    char word[LENGTH + 1];
    int index = 0;

    // load a word in line by line
    while(fscanf(file, "%s", word) != EOF)
    {
        printf("Word loaded %s\n", word);

        // scan loaded word character by character
        for(int i = 0; i < strlen(word); i++)
        {
            // remove any capital letters
            if(isalpha(word[i]) && isupper(word[i])) tolower(word[i]);

            // set current character in word to it's alphabetical index (apostrphes index is 26)
            index = word[i] - 'a';
            if(word[i] == '\'') index = 26;

            printf("Char being searched %c Index %i\n", word[i], index);

            // if character does not exist, create a new node and point root to it
            if(root->children[index] == NULL) root->children[index] = makeNewNode();

            // move to next node
            root = root->children[index];

            printf("Children's value: %p\n", (void *) root->children[index]);
        }
    // indicate leaf or end of branch
    root->endOfWord = true;
}

// close dictionary
fclose(file);

return true;
}

makeNewNode 函数

// function to automate initialization of nodes
trieNode* makeNewNode()
{
    // give some space for the new node
    struct trieNode* newNode = malloc(sizeof(trieNode));

    newNode->endOfWord = false;

    // initialize all children pointers to NULL.
    for (int i = 0; i < 27; i++) newNode->children[i] = NULL;

    return newNode;
}

【问题讨论】:

  • 您应该分别隔离和调试每个功能。例如,将scan loaded word character by character 部分实现为以单词作为输入的独立函数,然后使用一些输入对其进行测试以确保其正常工作(换句话说,删除文件读取代码)。

标签: c trie cs50


【解决方案1】:
 if(root->children[index] == NULL) root->children[index] = makeNewNode();

            // move to next node
            root = root->children[index];

你在这里修改root。所以对于下一个wordroot不是实际的根,而是插入数据的最后一个节点。你需要保持原来的根。

【讨论】:

  • 会这样吗? trieNode *tmpNode = root; 然后将所有正在做的事情替换为 roottmpNode 代替
猜你喜欢
  • 2019-03-20
  • 2014-06-16
  • 1970-01-01
  • 2012-07-28
  • 2014-01-15
  • 1970-01-01
  • 2022-11-20
  • 2022-10-23
  • 2022-09-25
相关资源
最近更新 更多