递归遍历字典尝试以计算总字数

Recursively traverse dictionary trie to count total words

本文关键字:计算 遍历 字典 递归      更新时间:2023-10-16

我已经从链表中构建了一个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;
}

您按值传递count,这意味着当递归解开并且只返回一个"最远"的时,它超出了范围,因为这是第一个递增的count,它只是 1。改为按引用传递int recursiveCount(Node* temp, int& temp);

正如在其他答案中已经指出的,您的问题是您有不同的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! */
}

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

递归代码中的重大错误是没有添加在每个后续节点中找到的每个 '$'。 特别是,您的代码仅返回 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
}