我在跟踪递归函数方面遇到了一些困难。例如,以字符串置换的以下函数为例:
void string_permutation(string str, int mid, int end)
{
if (mid == end)
cout << str << endl;
else
{
for (int i = mid; i <= end; i++)
{
swap(str[mid], str[i]);
string_permutation(str, mid + 1, end);
swap(str[mid], str[i]);
}
}
}
给定输入,说"abcd"
并通过以下方式调用:
string str = "abcd";
string_permutation(str, 0, str.size()-1);
我怎样才能快速(通过手动跟踪,即没有调试器,考虑你正在接受采访)找出这样的功能的第10个输出?更一般地说,如何跟踪递归函数?
答案 0 :(得分:1)
向方法调用添加迭代计数,然后在第10次调用(或任何你想要的)上调试:
void string_permutation(string str, int mid, int end, int iterationCount)
{
// Bump up our iterationCount
iterationCount += 1;
// Debug on 10th call
if (iterationCount == 10)
Debug.WriteLine("10th call: " + str + ", " + mid + ", " + end);
if (mid == end)
cout << str << endl;
else
{
for (int i = mid; i <= end; i++)
{
swap(str[mid], str[i]);
string_permutation(str, mid + 1, end, iterationCount);
swap(str[mid], str[i]);
}
}
}
您可以使用以下方法调用该方法:
string str = "abcd";
string_permutation(str, 0, str.size()-1, 0);
答案 1 :(得分:1)
只需在 cout << str << endl;
上插入断点即可。并且,跳过九次突破。它看起来很脏,但我觉得很简单。
用笔和纸:我会写参数。
("abcd", 0, 3)
然后,让程序在我的大脑中运行直到递归调用。那时,我再次写参数。
("abcd", 0, 3)
("bacd", 1, 3)
继续。
("abcd", 0, 3)
("bacd", 1, 3)
("bcad", 2, 3)
("bcda", 3, 3)
当函数返回时,擦除最后一行并写入返回值。 (你的函数返回void,所以我只写“return”)
("abcd", 0, 3)
("bacd", 1, 3)
("bcad", 2, 3)
return
然后继续。当程序递归调用或再次返回时,擦除最后一个“返回”标记并写入那里。
("abcd", 0, 3)
("bacd", 1, 3)
return
您想跟踪cout << str << endl;
,因此将标准输出写入另一篇论文会很有用。 (如果代码很复杂,你可以需要更多的纸张,例如“变量图”。)
我的想法类似于计算机处理递归函数的方式。在这种情况下,“纸张”用作堆栈,我的大脑充当CPU。
如果您紧紧填写纸张,将抛出 StackOverflowException 。但别担心。也许你有很多张纸!
答案 2 :(得分:1)
实际上没有修复规则来调试适合所有模式的递归函数,尽管有一些方法可以追踪它.. please follow this link for more detail..
除此之外,你可以使用print
语句找出每次递归的值。