JAVA 中的方法和递归(汉诺塔和青蛙跳台阶)

发布于:2022-11-04 ⋅ 阅读:(628) ⋅ 点赞:(0)

方法定义及使用

什么是方法?
Java 中的方法和 C 语言里的函数类似,就是一些语句的集合,组成在一起执行一个功能。它是解决一类问题的有序组合,包含于类或对象中,在程序中被创建,在其他地方被调用。

方法的优点:

  1. 使程序变得简短而清晰
  2. 有利于程序维护
  3. 提高程序开发的效率
  4. 提高了代码的重用性

方法定义格式

修饰符 返回值类型 方法名称([参数类型 形参 ...]){
方法体代码;
[return 返回值];
}

例如:求两个数中较大的一个数:

    public static int getMax(int num1, int num2) {
    //方法体
        int tmp;
        if (num1 > num2) {
            tmp = num1;
        } else {
            tmp = num2;
        }
        return tmp;
    }

方法解析
当然,上面这个求较大值的方法可以写得更简便一点:

public static int getMax(int num1, int num2) {
	return num1 > num2 ? num1 : num2;
}

方法调用:

我们可以根据方法的返回值来选择调用:

public static void main(String[] args) {
   	int res=getMax(10,20);		//通过变量来接收方法的返回值
    System.out.println(res);
    System.out.println(getMax(11,22));		//直接输出方法的返回值
}

运行结果:
函数调用

对于有返回值的方法,我们可以根据返回值的类型,用相应的变量来接收,也可以直接输出。无返回值的方法,我们就不需要用变量来接收了。
下面这个程序就是调用无返回值的方法:
无返回值

方法重载

为什么会出现方法重载?
首先来看这个问题:当我们需要求两个 int 型的较大值,我们就可以调用上面的 getMax 方法,但是当我们想求两个 double 型的较大值的时候,就要重新定义一个能接受两个 double 型参数的方法,为了解决这种现象,我们就可以重载方法。
在 Java 中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了。

具体使用案例:

    //求两个 int 型的和
    public static int add(int num1, int num2) {
        return num1 + num2;
    }

    //求三个 int 型的和
    public static int add(int num1, int num2, int num3) {
        return num1 + num2 + num3;
    }

    //求两个 double 型的和
    public static double add(double num1, double num2) {
        return num1 + num2;
    }

    public static void main(String[] args) {
        add(5, 10);         //调用add(int num1, int num2)
        add(2, 3, 4);       //调用add(int num1, int num2, int num3)
        add(2.3, 3.4);      //调用add(double num1, double num2)
    }

注意:

  1. 方法名必须相同(例如上面的方法名都是 add)
  2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同),类型的次序不同是指 有一个方法 int 在前,double 在后,那另一个方法就 double 在前,int 在后。
  3. 与返回值类型是否相同无关。

递归

相信大家早有耳闻,递归的本质其实就是方法自己调用自己。
将一个大问题化成小问题,而小问题和大问题又相似,这时,我们就可以使用递归来解决这个问题。

案例一:
我们需要求 5 的阶乘,5!= 5*4*3*2*1。
我们发现:5!其实就等于 5*4!,而 4!= 4 * 3!,以此类推,我们就可以得到一个递归公式:f(5) = 5 * f(4)。把 5 换成 n 后,我们就得到了求 n!的公式:f(n) = n * f(n-1)

所以,我们可以根据上面的推导写出下面这个程序:

public static int fact(int n) {
    if (n == 1) {
        return 1;  //1的阶乘是1,直接返回
    }
    int res = n * fact(n - 1);
    return res;
}

public static void main(String[] args) {
    System.out.println(fact(5));    //120
}

递归方法执行过程:
递归过程


可能有些凌乱,将就看一下。

案例二: 按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)
我们要顺序打印 1 2 3 4,要打印 4 ,就要先打印 3,1就是最先打印的,那就要让 1234 变成 1 位数,直接输出,不是 1 位数,就除 10,然后取余,就能拿到最后 1 位数。

代码:

public static void func(int n) {
    if (n<10){
        System.out.println(n);
        return ;
    }
    func(n/10);
    System.out.println(n%10);
}
public static void main(String[] args) {
    func(12345);
}

运行结果:
运行结果
递归过程:
顺序打印数字每一位

汉诺塔

汉诺塔游戏:将 A柱 上的方块按大小顺序通过 B柱 移动到 C柱,移动过程中规定,小方块上不能放大方块,在三个柱子间,一次只能移动一个方块。例如下面这个动画:

汉诺塔
我们先定义两个方法:一个用于表示方块数和柱子的信息。

public static void hanoi(int n, char posA, char posB, char posC){
//n 表示有n个方块,posA,posB,posC分别表示柱子A,柱子B和柱子C
//A可以理解为起始,C为终点,B为中转
}

另一个方法用来移动方块:

public static void move(char pos1, char pos2){
//从柱子1移动到柱子2
}

第一种情况(只有一个方块):
一个

只有一个时,我们就可以直接移动:

 if (n == 1) {
    move(posA, posC);//从A移动到C
    return;
}

第二种情况(两个方块):我们就需要借助 B 柱,先将 A 柱上的小方块移动到 B 柱上,然后才能将 A 柱上的大方块移动到 C 柱上,最后再将 B 柱上的移动到 C 住上,完成移动:

将n-1个从A通过C先移动到Bhanoi(n - 1, posA, posC, posB);
再将A上的最后一个移动到Cmove(posA, posC);
然后在将B上的n-1个通过A移动到Chanoi(n - 1, posB, posA, posC);

两个方块

当有3个方块时:我们想把A上的第3块移动到C,那只能把A上的1和2先移动到B,就像上面图中一样移动2个方块,只是上面是通过B移动到C,而这次是通过C移动到B。

三个方块
先使n-1个移动到B
在这里插入图片描述

根据上面的规律,我们就可以得出:
要想将A上面的N个方块顺序移动到C上时,我们就需要把A上面的N-1个方块通过C先移动到B上面:

hanoi(n - 1, posA, posC, posB);

此时A上面就只剩第N块,也就是最后一块,这就和第一种情况一样,直接移动到C就行:

move(posA, posC);

那现在还有N-1个方块还在B上面,那我们就需要把这N-1个通过A移动到C:

hanoi(n - 1, posB, posA, posC);

完整代码:

public class Demo {
    public static void hanoi(int n, char posA, char posB, char posC) {
        if (n == 1) {
            move(posA, posC);
            return;
        }
        hanoi(n - 1, posA, posC, posB);
        move(posA, posC);
        hanoi(n - 1, posB, posA, posC);
    }

    public static void move(char pos1, char pos2) {
        System.out.print(pos1 + "->" + pos2+" ");
    }

    public static void main(String[] args) {
        hanoi(3, 'A', 'B', 'C');
    }
}

运行结果:
汉诺塔运行结果

青蛙跳台阶

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

牛客网在线刷题链接:青蛙跳台阶

解析过程:
跳台阶
代码:

public class Solution {
    public int jumpFloor(int target) {
        if(target==1){
            return 1;
        }
        if(target==2){
            return 2;
        }
        return jumpFloor(target-1)+jumpFloor(target-2);
    }
}

以上就是本次的全部内容,如有帮助,还望点赞支持一下。

本文含有隐藏内容,请 开通VIP 后查看