手动跟踪递归函数

时间:2014-01-20 09:07:40

标签: c++ recursion

我在跟踪递归函数方面遇到了一些困难。例如,以字符串置换的以下函数为例:

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个输出?更一般地说,如何跟踪递归函数?

3 个答案:

答案 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语句找出每次递归的值。