美文网首页
递归与循环

递归与循环

作者: jiamjg | 来源:发表于2018-10-20 15:57 被阅读0次

理论上,任何循环都可以重写为递归形式。
有些语言没有循环语句,只能使用递归。

循环改递归
  • 改为递归的关键是发现逻辑“相似性”
  • 不要忘记递归“出口”

例1:打印从1到n的整数。

下面的代码是通过for循环实现:

public class 递归1_循环 {
    public static void main(String[] args){
        for(int i=0;i<10;i++){
            System.out.println(i);
        }
    }
}

如果用递归,可以有以下思路:
我负责打印最后一个,但是我前面的人负责打印0-n-1个
由这个思路,通过这样的代码来实现:

public class 递归1_循环 {
    public static void main(String[] args){
        f(9);
    }
    public static void f(int n){
        if(n>=0){
            f(n-1);
            System.out.print(n+" ");
        }
    }
}

所以,我们可以拓展成这样:

public class 递归1_循环 {
    public static void main(String[] args) {
        f(0, 9);
    }
    public static void f(int begin, int end) {
        if (begin > end) {
            return;
        }
        System.out.print(begin+" ");
        f(begin + 1, end);
    }
}
构造相似性
  • 如果没有明显的相似性,需要主动构造。
  • 不能相似的原因很可能是缺少参数
  • 递归与数学上的递推公式很类似。

例2:数组求和

可通过for循环来实现这个需求:

public class 递归2_求和 {
    public static void main(String[] args){
        int []a={1,2,3,4,5,6,7,8,9,10};
        System.out.println(f(a));
    }
    public static int f(int []a){
        int x=0;
        for (int i=0;i<a.length;i++){
            x+=a[i];
        }
        return x;
    }
}

通过递归实现:
如果用递归实验,目前有三种思路:

  1. a[begin]+(begin+1......结束)。
  2. (a[0]...end-1)+a[end]。
  3. 折半求和 mid=(begin+end)/2,[begin,mid)[mid,end)。

下面是第一个思路:

public class 递归2_求和 {
    public static void main(String[] args){
        int []a={1,2,3,4,5,6,7,8,9,10};
        System.out.println(f(a,0));
    }
    public static int f(int []a,int begin){
        if(a.length==0)
            return 0;
        if(a.length<=begin){
            return 0;
        }
        return a[begin]+f(a,begin+1);
    }
}

慢慢地发现,递归就是一个踢皮球的游戏。

例3:字符串匹配

用equals函数来实现:

import java.util.Arrays;
public class 递归3_字符串匹配 {
    public static void main(String[] args){
        String a="abc";
        String b="abc";
        System.out.println(f(a,b));
    }
    public static boolean f(String a,String b){
        return a.equals(b);
    }
}

用递归来实现:

import java.util.Arrays;
public class 递归3_字符串匹配 {
    public static void main(String[] args){
        String a="abc";
        String b="abc";
        System.out.println(f(a,b));
    }
    public static boolean f(String a,String b){
        if(a.length()!=b.length()){
            return  false;
        }
        if(a.length()==0){
            return true;
        }
        if(a.charAt(0)!=b.charAt(0)){
            return false;
        }else{
            return f(a.substring(1),b.substring(1));
        }
    }
}

例4:求阶乘

public class Factorial {
    public static int fact(int n) {
        int result;
        if(n==1||n==0) {
            result=1;
        }else {
            result=n*fact(n-1);
        }
        return result;
    }
    public static void main(String[] args) {
        System.out.println(fact(5));
    }
}
递归调用
  • 递归调用仅仅是被调函数恰为主调函数
  • 注意每次调用的层次不同
  • 注意每次分配形参并非同一个变量
  • 注意返回的次序
现实中的“递归”

递归思想:
我做最后一个/我做第一个,你告诉我谁是最后一个(加参)
然后其他的交给长得跟我一样的下属。(相似性)
并且要求你到什么时候就不能往下交了(设置出口)

递归类型:有返回&没返回
没返回:老板做(【需要加参】或尾),然后推给下属,并限定到哪
有返回:老板最后返回总的情况,推给下属,限定到哪,底层下属返回一个

使用递归的步骤
  • 找重复
  1. 找到一种划分方法
  2. 找到递推公式或者等价转换(都是父问题转换为求解子问题)
  • 找变化的量
    变化的量通常要作为参数
  • 找到出口
    根据参数变化的趋势,对边界进行控制,适时终止递归

相关文章

  • 领扣算法12:整数转换为罗马数字

    题目描述: 递归实现: 循环实现: 递归与循环的比较:

  • 递归与循环

    一.递归与循环 递归,说白了就是自己调用自己。理论上,任何的循环都可以重写为递归形式,所有的递归也可以被表述成循环...

  • 递归与循环

    理论上,任何循环都可以重写为递归形式。有些语言没有循环语句,只能使用递归。 循环改递归 改为递归的关键是发现逻辑“...

  • 递归与循环

    一 题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序...

  • 递归与循环

    一直听说“递归的效率不如循环”,“递归会爆栈”等等说法。想这这里深入分析下递归与非递归的区别。先看看下面的例子代码...

  • 递归入门

    1.递归求前n项和 所有循环都可以转化为递归,而递归大多数可以转换为循环 2.递归求最大值 数组第一个下标与最后一...

  • 循环与递归对比

    大学学习递归的时候有一句话印象深刻:所有的递归都可以改写为循环。这句话我是同意的,因为递归其实本质上就是栈的操作。...

  • 谈谈递归与循环

    谈谈递归与循环很久没有写技术文章了,重新提笔希望这次能坚持下去。端午小长假随手给游戏的公会写了一个抽奖程序,在写抽...

  • 6.模块、函数与变量作用域

    循环与使用场景 while 解决问题的基本思维模式多用于递归,其他场景,推荐使用for循环。 for 与 for ...

  • 递归

    递归不用循环,调用自身循环,上诉代码为递归,它的普通形式如下:

网友评论

      本文标题:递归与循环

      本文链接:https://www.haomeiwen.com/subject/dryavftx.html