递归与循环

递归与循环

有如下代码:

public static void main(String[] args)
{
    for (int i = 0; i <10 ; i++)
    {
        System.out.println(i);
    }
}

循环打印0-9.若是采用递归形式便是,可以定义函数print,利用if循环打印出n的值。

public static void print(int n)
{
    if (n>=0)
    {
        print(n-1);
        System.out.println(n);
    }
}
 public static void main(String[] args)
 {
      print(9);
 }

关键是找到相似性。

print方法还可以这样写,if只执行一条语句,可以这样写(C语言)

public static void print(int n)
{
    if (n>0) print(n-1);
    System.out.println(n);
    
}

方法二:用户角度出发定义begin 和end代表起止

public static void print(int begin,int end)
{
    if (begin>end) return;//判断起是否大于止
    System.out.println(begin); //打印begin
    print(begin+1,end);//实现begin+1
    
}
 public static void main(String[] args)
 {
     print(0,9);//输入起止
 }

递归是一种灵活的写法,并非只有一种写法。

改用递归关键是发现逻辑的相似性,不要忘记递归的出口!

递归与数学上的递推公式相似,如果没有相似性,需要主动构造。不能相似的原因很可能是缺少参数。 (大量练习,找到感觉)

例2:求数组之和

有一个数组,现在需要求数组之和。

不难想到遍历数组,再每项相加。但我们不妨定义一个add方法将操作都放在方法之内。main方法负责数组的定义与结果的输出,可以得到有如下代码:

public class Test2
{
    public static int add(int[] a)
    {
        int x = 0;
        for (int i = 0; i < a.length; i++) x += a[i];
        return x;
    }

    public static void main(String[] args)
    {
        int[] a = {2, 3, 4, 5, 6, 7};

        System.out.println(add(a));

    }


}

但上述代码貌似与递归毫无关系,如果要使用递归满足需求,不妨考虑二分法,或者踢皮球的思想。

我们可以定义一个add方法传入数组a和起始值begin,当begin与a.length的长度相等时,返回一个0,使结果不会失真。

public static int add(int[] a, int begin)
{
    if (begin == a.length) return 0;//求a数组中,从begin到结束的元素之和。返回一个0为了使最终值不失真
    int x = add(a, begin + 1);//定义x存储结果
    return x + a[begin];
}
 public static void main(String[] args)
    {
        int[] a = {2, 3, 4, 5, 6, 7};
        int sum = add(a, 0);//并非是初始值为0,而是说从第0项开始(数组下标第一项是0)
        System.out.println(sum);
    }

tip:还可以通过如下三种解法获取到结果

1.a[begin]+(begin+1+…+end)

2.(a[0]+…+end-1)+a[end]

3.折半求和:mid=(begin+end)/2,[begin,mid)+[mid,end]

例3:比较两个字符串是否相同

不难想到Java自带的equals去比较两个字符串是否相等,再返回一个布尔值

public class Test3
{
    public static  boolean compare(String s1,String s2)
    {
        return s1.equals(s2);
    }
    public static void main(String[] args)
    {
        System.out.println(compare("123","abc"));
    }
}

但如上所述,我们还是可以定义一个方法去比较二者是否相等,以取代Java自带的equals函数。代码如下:

public static boolean compare(String s1, String s2)
{
    if (s1.length() != s2.length()) return false;
    if (s1.length() == 0 && s2.length() == 0) return true;//此处可以只判断一个字符串是否为空,如果不是则第一个循环已经返回false

    if (s1.charAt(0) != s2.charAt(0)) return false;//判断首字符是否相同
    return compare(s1.substring(1), s2.substring(1));

}
public static void main(String[] args)
    {
//        System.out.println(compare("123", "abc"));
        System.out.println(compare("123","123"));
    }

递归调用:仅仅是被调函数恰巧为主调函数,且调用的层次不同

注意:每次返回的次序,每次分配的形参并非同一个变量

递归总的来说就是本代码调用本代码,因为栈结构是先进后出。

任何循环都是可以改成递归,需要找到相似性(可构造),注意递归的“出口”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值