提起递归,其实大多数的递归都可以转化成循环,因为递归与循环之间存在某种相似性。下面我们来讨论讨论将循环转化成递归的问题。
将循环改写成递归,主要分为以下两点:
1.寻找相似性,若没有明显的相似性,则可以通过添加参数来主动构造
2.寻找递归出口
下面来举两个例子:
1.给出一个数组,求数组的各项和
分析:看到这道题,我们的第一个想法就是利用循环来遍历每一个元素,并求和。但是我们已经说啦,循环大部分都可以改成递归,所以我们尝试把它改成递归。
现在声明函数int f3(int a[],int begin,int n),这个函数的用途是用来求数组a从下标begin开始到下标n的元素和,这个函数中一定有一个语句为int x =f3(a, begin+1, n);这个语句的用途是用来求数组a从下标begin+1开始到下标n的元素和,这个和保存在x中,由于函数的功能是求从begin开始的和,所以这里返回x+a[begin].下面我没问你寻找函数的递归出口,经过分析这个函数的出口可口为if (begin == n) { return0;},所以这个函数可以写成:
int f3(int a[],int begin,int n){
if (begin == n) {
return 0;
}
int x =f3(a, begin+1, n);
return x + a[begin];
}
这个问题还有另一种解决的方式,代码如下:
int f4(int a[],int end){
if (end == 0) {
return 0;
}
int x =f4(a, end-1);
return x + a[end];
}
下面我们来解决另一个问题:
2.给出两个字符串让我们来判断这两个字符串是否相同。
看到这道题我没问你第一个想法就先判断字符串长度是否相等,然后利用for循环来进行每个字符的比较。所以我们可以利用递归来解决这个问题。
分析:
我们的想法是先比较俩个字符串的长度是否相等,如果不相等,返回0,然后比较比较字符串的第一个位置字符是否相等,现在有函数声明int f5(char *str1,char *str2),这个函数体中有个语句用来判断字符串是否相等,if (strlen(str1) !=strlen(str2)) { return0; },还有语句if (str1[0] != str2[0]) { return0;},用来判断字符串的第一个语句是否相等,这里又还有一个最重要的递归调用returnf5(str1+1, str2+1);下面我们寻找递归出口,就是当字符串长度为0的时候,if (strlen(str1) ==0) { return1;},所以这个函数总体可以写成:
int f5(char *str1, char *str2){
if (strlen(str1) != strlen(str2)) {
return 0;
}
if (strlen(str1) == 0) {
return 1;
}
if (str1[0] != str2[0]) {
return 0;
}
return f5(str1+1, str2+1);
}