我发现递归,除了像阶乘这样的直截了当的递归之外,很难理解。下面的代码片段打印字符串的所有排列。有人能帮我理解吗。正确理解递归的方法是什么。
void permute(char a[], int i, int n)
{
int j;
if (i == n)
cout << a << endl;
else
{
for (j = i; j <= n; j++)
{
swap(a[i], a[j]);
permute(a, i+1, n);
swap(a[i], a[j]);
}
}
}
int main()
{
char a[] = "ABCD";
permute(a, 0, 3);
getchar();
return 0;
}
要在设计中有效地使用递归,可以通过假设已经解决了问题来解决问题。 当前问题的心理跳板是“如果我能计算出n-1个字符的排列,那么我就可以依次选择每个字符并附加其余n-1个字符的排列来计算n个字符的排列,我假装我已经知道该怎么做了”。
然后你需要一种方法来完成所谓的“触底”递归。因为每个新的子问题都比上一个小,也许你最终会得到一个你真正知道如何解决的子问题。
在这种情况下,你已经知道了一个角色的所有排列-它只是一个角色。所以你知道如何求解n=1,对于每一个数,这个数比你能求解的数多一个,你就完成了。这与所谓的数学归纳法密切相关。
它从所有可能剩下的字符中选择每个字符:
保罗的建议是对的。在理解代码之前,你必须用“手”(使用你想要的任何工具——调试器、纸张、记录函数调用和变量)来浏览代码。关于代码的解释,我将向您介绍quasiverse的优秀答案。
也许,这种调用图的可视化(字符串稍微小一点)使其工作方式更加明显:
这张图是用graphviz绘制的。
相关问题 更多 >
编程相关推荐