【问题标题】:Recursively traverse dictionary trie to count total words递归遍历字典尝试计算总单词数
【发布时间】:2017-09-03 11:00:00
【问题描述】:

我已经从一个链表构建了一个 trie。每个节点包含一个 char 和一个由 27 个节点组成的数组(字母 + 一个额外的 $ 表示单词结尾的点)。 我尝试编写一个递归方法来计算单词的数量,但它返回 1。我不确定如何修复它或到底出了什么问题。

int recursiveCount(Node* temp, int count)
{
    if (temp->value == '$')
    {
        count++;
    }
    for (int i = 0; i < 27; i++)
    {
        if (temp->array[i] != NULL)
        {
            return recursiveCount(temp->arr[i],count);
        }
    }
return count;
}

【问题讨论】:

    标签: c++ trie


    【解决方案1】:

    您通过值传递count,这意味着当递归解开时它超出范围,并且只有“最远”的一个被返回,因为这是第一个要增加的count,它只是1。通过通过引用代替int recursiveCount(Node* temp, int&amp; temp);

    【讨论】:

    • 我不太明白为什么它超出了范围。变量“count”递增,然后我将“count”的当前值返回给函数的下一次调用。我理解你所说的最远的被退回的意思
    • 我在凌晨 2 点回答了这个问题,老实说,我记不清我的思路了。对于那个很抱歉。希望我没有让你感到困惑。
    【解决方案2】:

    正如其他答案中已经指出的那样,您的问题是您有不同的 count 变量,每个递归调用一个变量。增加一个不会改变其他的。除了传递(非常量)引用之外,您还可以采用更实用的编程方法并从函数中返回计数。当然,您需要总结您进行的所有递归调用的返回计数:

    unsigned recursiveCount(Node const * node) /* you don't change the node, so make
                                                  it const. Why a pointer btw? A
                                                  reference would do fine! */
    {
        unsigned count = 0; /* You aren't expecting a negative number of
                               words, are you? So use unsigned. */
        if (node->value == '$')
        {
            count++;
        }
        for (int i = 0; i < 27; i++)
        {
            if (node->array[i] != NULL) /* "array"!? change that to a meaningful
                                           name ... "children" is bad, but not as
                                           bad as "array" ... */
            {
                count += recursiveCount(node->array[i]); /* "arr" was a typo I
                                                            suppose */
            }
        }
        return count; /* consistent indentation, please! */
    }
    

    【讨论】:

    • 这个方法似乎比我的方法更合乎逻辑,但由于某种原因它仍然返回 1。
    • @Chris 你的树可能有问题?你给这个函数什么输入,你期望什么输出?
    • 我已经非常彻底地测试了这棵树。插入和查找方法完美无缺。在调用递归函数的函数中,首先我声明一个临时指针并让它指向根。当我调用该函数时,我只需执行“return recursiveCount(temp);”
    • 哎呀对不起,1 实际上是正确的返回值。谢谢!
    • @Chris :) 不客气。不要忘记养成一个好习惯,并将您可能在运行此功能时针对的那些测试保留为单元测试。
    【解决方案3】:

    您已将其标记为 C++,所以我很困惑为什么该方法不是 Node.js 的一部分。见封装。

    递归代码中的重大错误不是添加在每个后续节点中找到的每个'$'。特别是,您的代码仅返回一次 for 循环调用的计数,所有其他都被丢弃。

    for (int i = 0; i < 27; i++)
    {
        if (temp->array[i] != NULL)
        {
            return recursiveCount(temp->arr[i],count);
            // This only returns one value,
            // and ignores all the other 26 possible values
            // these should sum together
        }
    }
    

    考虑使方法成为节点的一部分。请注意 retVal 如何累积找到的每个“$”。

    int Node::recursiveCount()
    {
        int retVal = 0; // accumulation
    
        if (value == '$') 
        { 
            retVal += 1;  // 1 word found here
        }
    
        // keep searching here, there might still be words with prefix
        for (size_t i = 0; i < 27; i++)
        {
            if (nullptr != nxt[i]) 
            {
                retVal += (nxt[i]->recursiveCount());
                //     ^^ accumulate any other words found
            }
        }
        return (retVal); // return full count
    }
    

    【讨论】:

    猜你喜欢
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多