【问题标题】:Simple recursive function to determine if two elements are transitively true确定两个元素是否传递真的简单递归函数
【发布时间】:2015-10-05 05:14:59
【问题描述】:

这里是新手。甚至更新到递归。我正在为我的 C++ 程序编写一个函数,正如您所知道的,我在递归算法方面有点无能为力。如果有人能修复我的函数,我将不胜感激,这样我就可以让它工作,并且可能对以后如何处理递归有更好的了解。

我的函数将布尔值的二维方阵、整数 i 和整数 array_size 作为参数。该函数返回一个布尔值。

数组是一个邻接矩阵,我用它来表示一组条件。例如,如果 [0][3] 处的值为真,则 0 -> 3(如果为 0,则为 3)。如果 [3][7] 为真,则 3 -> 7(如果为 3,则为 7)。通过传递性,0 -> 7(如果为 0,则为 7)。

整数 i 是条件集合中的一个特定元素。如果此元素可传递地连接到数组中的最后一个元素,则该函数将返回 true。数组的最后一个元素是整数(array_size - 1),

整数array_size是方阵每个维度的大小。如果 array_size 为 20,则数组为 20x20。

这个函数的思想是通过传递属性判断从第一个整数元素到最后一个整数元素是否有任何逻辑“路径”。当路径存在时,函数返回true,否则返回false。递归调用应该允许它遍历所有可能的路径,当它最终到达最后一个元素时返回 true,如果所有路径都失败则返回 false。

例如,如果 i = 0 且 array_size = 10,则函数将根据矩阵和传递属性提供的条件返回 0 -> 9 是否有效。

这是我目前的代码:

bool checkTransitivity(bool **relations, int i, int array_size){
bool isTransitive = false;

if (i == array_size - 1)
{
    isTransitive = true;
}
else
{
    for (int j = i; j < array_size; j++){
        if (relations[i][j])
        {
            isTransitive = checkTransitivity(relations, j, array_size);
        }
    }
}

return isTransitive;

目前,该函数对所有输入都返回 true。

感谢任何帮助。提前致谢!

【问题讨论】:

  • 您或许应该提供一个输入示例。事实上,代码不能总是返回 true。

标签: c++ arrays recursion adjacency-matrix


【解决方案1】:

编辑:由于您的 if-else 语句,这第一部分是不必要的。转到 END OF EDIT。

让我们从递归函数的基本情况开始:

if (i == array_size - 1)
{
    isTransitive = true;
} 

好吧,您确实有一个基本情况,但没有返回任何内容。您只是将标志设置为 true。你想做的是:

if (i == array_size - 1) {
    return true;
}

现在该函数将在递归堆栈中向上工作以返回 true。编辑结束。

但我们仍然需要修复递归情况:

else {
    for (int j = i; j < array_size; j++) {
        if (relations[i][j]) {
            isTransitive = isTransitive || checkTransitivity(relations, j, array_size);
        }
    }
}

return isTransitive;

|| 表示二进制或。所以你的逻辑是对的。您想检查每条可能的路径以查看它是否可以到达那里,但是通过将 isTransitive 设置为每次检查的结果,isTransitive 只会设置为最后一次调用。通过执行isTransitive = isTransitive || recursive call,只要其中一个调用产生一个真值,isTransitive 就会为真。

我要说的最后一点是警告:如果relations[i][j] == true 和relations[j][i] == true,您的代码仍将处于无限循环中。您必须找到一种方法来消除潜在的回溯。一种方法是创建另一个数组来存储您已经检查过的路径,这样您就不会无限循环。

更多信息可以在这里找到:Depth First Search

【讨论】:

    【解决方案2】:

    我认为你只需要一个break 条件来在遇到非传递项时停止继续循环。见下文(未测试)

    bool checkTransitivity(bool **relations, int i, int array_size){
    bool isTransitive = false;
    
    if (i == array_size - 1)
    {
        isTransitive = true;
    }
    else
    {
        for (int j = i; j < array_size; j++){
            isTransitive = relations[i][j] && checkTransitivity(relations, j, array_size);
            if (!isTransitive)
                break;
        }
    }
    
    return isTransitive;
    }
    

    【讨论】:

    • 不幸的是,这仍然 100% 的时间返回 true。
    • 也许我没有正确理解你的问题。您能否发布您的完整程序,包括测试(带有示例 relations 数组和预期结果)?
    猜你喜欢
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多