假设我有这样的事情:(预测输出)
void abc (char *s){
if(s[0]=='\0')
return;
abc(s+1);
abc(s+1);
printf(“%c “, s[0]);
}
解决起来并不难,但是我花了太多时间,而且我必须重做这样的问题 2-3 次,因为我忘记了变量的递归和值(尤其是当有 2-3 个这样的递归语句时)
当必须解决此类问题时,有什么好的方法可以使用吗?
基本技术是首先从少量输入开始。然后尝试使用更大的。然后尝试使用比这更大的一个。对于递归函数,应该出现一种模式,让您可以预测下一个函数的外观,前提是您知道前一个函数的外观。
所以,让我们从一个空字符串开始。很简单,什么都没有打印。
input: ""
output:
接下来是长度为 1 的字符串。几乎同样简单,两个递归调用每个都不做(空字符串大小写),然后打印字符串的字符。
input: "z"
output: z
接下来是一个长度为 2 的字符串。每个递归调用最终都会打印第二个字符(长度为一个大小写的字符串),然后打印第一个字符。
input: "yz"
output: zzy
因此,让我们尝试预测长度为 3 的字符串会发生什么情况。将会发生的是排除第一个字符的子字符串被处理两次,然后打印第一个字符。该子字符串是长度为两种情况的字符串。所以:
input: "xyz"
output: zzyzzyx
因此,现在应该清楚如何在给定当前输出序列的情况下推导出下一个输出序列。
拿一摞大小合适的索引卡。开始跟踪对递归函数的初始调用。当您接到另一个电话时,请启动一张新的索引卡,并将其放在第一张卡的前面或后面(视情况而定)。您迟早会(除非您正在跟踪无限递归)跟踪不进行递归调用的调用的执行,在这种情况下,将返回值复制回您来自的卡。
在您的卡片上包含“前往卡片 X”和“来自卡片 Y”可能是个好主意。
在复杂的情况下,您可能会发现创建多个卡片堆栈来跟踪您的函数调用很有用,哦,为什么不叫它们调用堆栈。