【问题标题】:Error Executing Trie Tree执行 Trie 树时出错
【发布时间】:2017-06-06 09:15:26
【问题描述】:

我想插入一个字符串并使用 trie 数据结构进行搜索操作。这是我第一次使用指针实现,所以我真的很困惑我在代码中做错了什么,它给出了编译错误。请帮助调试请告诉我我的指针逻辑有什么问题。

typedef struct trie {
    unordered_multimap<char, struct trie> child;
    bool isEnd;
} trie;
trie* newtrienode()
{
    trie* newnode = (trie*)malloc(sizeof(trie));
    newnode->isEnd = false;
    return newnode;
}
trie* root = newtrienode();
void insert(string word)
{
    trie* current = root;
    for (int i = 0; i < word.length(); i++) {
        char ch = word[i];
        trie* node = current->child[ch];
        if (node == NULL) {
            trie* node = newtrienode();
            current->child.insert(pair<char, trie>(ch, node));
        }
        current = node;
    }
    current->isEnd = true;
}
bool search(string word)
{
    trie* current = root;
    for (int i = 0; i < word.length(); i++) {
        char ch = word[i];
        trie* node = current->child[ch];
        if (node == NULL) {
            return false;
        }
        current = node;
    }
    return true;
}

【问题讨论】:

    标签: c++ algorithm data-structures hashmap trie


    【解决方案1】:

    除了在 cmets 中提到的之外,我发现代码存在一些问题。

    1.

    trie* newnode = (trie*)malloc(sizeof(trie));
    

    这不会创建trie 类型的对象,它只分配trie 大小的内存块并将指向它的指针分配给变量newnode。特别是,它不调用unordered_multimap 的构造函数。通过该指针对child 成员的任何访问都会产生未定义的行为。此外,你永远不会释放那段内存。

    2.

    typedef struct trie {
        unordered_multimap<char, struct trie> child;
        bool isEnd;
    } trie;
    

    在第二行,您将声明一个具有不完整类型 trieunordered_multimap 数据成员作为第二个模板参数。一些编译器允许这样做,但标准并不要求它们这样做。另一方面,shared_ptr 需要可用于不完整类型作为模板参数。此外,一个节点每个字符只能有一个子树,因此您不需要多重映射;一张地图就足够了。所以我建议使用unordered_map&lt;char, shared_ptr&lt;trie&gt;&gt; 并将所有出现的trie* 替换为shared_ptr&lt;trie&gt;。一旦root 被释放,它也会负责删除对象。

    newtrienode() 函数将如下所示:

    shared_ptr<trie> newtrienode()
    {
        shared_ptr<trie> newnode (new trie());
        newnode->isEnd = false;
        return newnode;
    }
    

    3.

    trie* node = current->child[ch];
    if (node == NULL) {
    

    当密钥不存在时,operator[] 不会返回 NULL。它将默认构造的对象插入到容器中并返回对它的引用。要检查密钥是否存在,请使用findcount

    4.

    trie* node = current->child[ch];
    if (node == NULL) {
        trie* node = newtrienode();
        current->child.insert(pair<char, trie>(ch, node));
    }
    current = node;
    

    请注意,在第三行中您要声明一个新变量。第一行声明的变量node 没有改变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 2018-05-13
      • 2012-02-25
      • 2018-08-05
      • 2015-01-01
      相关资源
      最近更新 更多