Java 一些简单的编程思想和算法 韩顺平跟学

方法递归调用

方法递归调用

斐波那契

逆向思维

package com.exrecursion;

import org.junit.Test;

/**
 * 递归:斐波那契
 *
 * @author wty
 * @date 2022/11/11 23:51
 */
public class RecursionEx {
    @Test
    public void recursionEx() throws Exception {
        int i = fibonacci(0);
        System.out.println(i);
    }
    public int fibonacci(int n) throws Exception {
        //1.请使用递归的方式求出斐波那契数1,1 ,2,3,5,8,13...给你一个整数n,求出它的值是多

        /** 序号 和
         *  1    1
         *  2    1
         *  3    2
         *  4    3
         *  5    5
         *  6    8
         *  7    13
         *
         */
        if (n <= 0){
            throw new Exception("输入的数据有误");
        }
        if (n== 1 || n == 2){
            return 1;
        }

        return fibonacci(n-1) + fibonacci(n-2);
    }

    /**
     * 逆向思维
     *
     * @param
     * @return void
     * @date 2022/11/12 0:12
     * @author wty
     **/
    @Test
    public void monkeyEatPeach(){
        //2.猴子吃桃子问题:有一堆桃子,猴子第一天吃了其中的一 半,并再多吃了一个!以后
        //每天猴子都吃其中的一半,然后再多吃一个。当到第10天时,想再吃时(即还没吃)
        //发现只有1个桃子了。问题:最初共多少个桃子?

        /**
         * 第i天  桃子
         * 10     1
         *  9     4
         *  8     10
         *  7     22
         *  6     46
         */
        int n = 1;
        int i = PeachNums(1,10);
        System.out.println("最初有"+i+"个桃子");
    }

    public int PeachNums(int nums,int day){
        for (int i = day - 1; i >= 1; i--) {
            nums = (nums + 1) * 2;
            System.out.println("第"+i+"天有" +nums+ "个桃子");
        }
        return nums;
    }
}

迷宫问题

迷宫问题

策略:下右上左

package com.maze;

import org.junit.Test;

/**
 * 老鼠迷宫
 *
 * 老鼠初始位置:(1,1)
 *
 * 老鼠逃离迷宫位置:(6,5)
 *
 * @author wty
 * @date 2022/11/12 0:19
 */
public class Maze {
    @Test
    public void maze(){
        // 迷宫 8 行 7  列
        int maze[][] = new int[8][7];
        // 0 表示无障碍物, 1 表示有障碍物
        System.out.println(maze[0].length);
        System.out.println(maze.length);
        /**
         * 7 列
         * 8 行
         */

        // 四周设置障碍物
        // 1. 最上面一行和最下面一行设置障碍物
        for (int j = 0; j < maze[0].length; j++) {
            maze[0][j] = 1;
        }
        for (int j = 0; j < maze[7].length; j++) {
            maze[7][j] = 1;
        }

        // 2. 最左边一列和最右面一列设置障碍物
        for (int i = 0; i < maze.length; i++) {
            maze[i][0] = 1;
        }

        for (int i = 0; i < maze.length; i++) {
            maze[i][6] = 1;
        }

        // 3.第四行左边三个设置障碍物
        for (int j = 0; j < 3; j++) {
            maze[3][j] = 1;
        }

        // 遍历
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }


        new Mouse().findway(maze,1,1);

        System.out.println("=====找到路后:=====");
        // 遍历
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }


    }

    class Mouse{
        // 使用递归回溯的思想来解决老鼠出迷宫
        /**
         * 找路
         *
         * @param
         * @param: map 迷宫
         * @param: i 老鼠的横坐标
         * @param: j 老鼠的纵坐标
         * @return boolean
         * @date 2022/11/12 0:34
         * @author wty
         **/
        public boolean findway(int map[][],int i,int j){
            // 规定map地图的规则
            // 0 表示无障碍物, 1 表示有障碍物
            // 2 表示可以走的路  3 死路
            // 获胜条件,当map[6][5] = 2 就说明找到通路了,否则就继续找
            // 先确定一个找路的策略 下右上左
            if (map[6][5] == 2){
                return true;
            }else if (map[i][j] == 0){
                // 表示无障碍物
                // 假定可以走通设置为2
                map[i][j] = 2;

                // 用找路策略来测试是否可以真的走通
                // 下右上左

                if (findway(map,i+1,j)){
                    // 下
                    return true;
                }else if (findway(map,i,j+1)){
                    // 右
                    return true;
                }else if (findway(map,i-1,j)){
                    // 上
                    return true;
                }else if (findway(map,i,j-1)) {
                    // 左
                    return true;
                }else {
                    map[i][j] = 3;
                    return false;
                }


            }else {
                //  map[i][j] == 2 || map[i][j] == 1 || map[i][j] == 3
                return false;
            }


        }
    }
}

输出结果

7
8
1	1	1	1	1	1	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	1	1	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	1	1	1	1	1	1	
=====找到路后:=====
1	1	1	1	1	1	1	
1	2	0	0	0	0	1	
1	2	2	2	0	0	1	
1	1	1	2	0	0	1	
1	0	0	2	0	0	1	
1	0	0	2	0	0	1	
1	0	0	2	2	2	1	
1	1	1	1	1	1	1	

策略:右下左上

package com.maze;

import org.junit.Test;

/**
 * @author wty
 * @date 2022/11/12 10:02
 */
public class Maze02 {
    @Test
    public void maze(){

        // 初始化地图
        int maze[][] = new int [8][7];

        // 无障碍物为0  有障碍物为1
        // 将第一行和最后一行设置障碍物
        System.out.println(maze.length);
        for (int i = 0; i < maze.length - 1; i++) {
            maze[0][i] = 1;
            maze[7][i] = 1;
        }

        // 将第一列和最后一列设置障碍物
        for (int i = 0; i < maze[0].length; i++) {
            maze[i][0] = 1;
            maze[i][6] = 1;

        }

        // 将第四行增加障碍
        maze[3][1] = 1;
        maze[3][2] = 1;

        System.out.println("=====找路前遍历=====");
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }

        // 定义老鼠初始位置
        findway(maze,1,1,2);

        System.out.println("=====找路后遍历=====");
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }

    }

    public boolean findway(int maze[][],int i,int j,int step){
        if (!(i>=0 && i<= maze.length && j >=0 && j<= maze[i].length)){
            return false;
        }
        // 0 无障碍
        // 1 有障碍
        // 2 通路
        // 3 死路

        if (maze[6][5] == 2){
            return true;
        }else if (maze[i][j] == 0){
            maze[i][j] = step;
            // 右下左上顺序
            if (findway(maze,i,j+1,2)){
                return true;
            }else if(findway(maze,i+1,j,2)){
                return true;
            }else if(findway(maze,i,j-1,2)){
                return true;
            }else if(findway(maze,i-1,j,2)){
                return true;
            }else {
                maze[i][j] = 3;
                return false;
            }
        }else {
            return false;
        }
    }


}

输出结果

8
=====找路前遍历=====
1	1	1	1	1	1	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	1	1	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	1	1	1	1	1	1	
=====找路后遍历=====
1	1	1	1	1	1	1	
1	2	2	2	2	2	1	
1	0	0	0	0	2	1	
1	1	1	0	0	2	1	
1	0	0	0	0	2	1	
1	0	0	0	0	2	1	
1	0	0	0	0	2	1	
1	1	1	1	1	1	1	

测试回溯现象

package com.maze;

import org.junit.Test;

/**
 * @author wty
 * @date 2022/11/12 10:46
 */
public class Maze03 {
    @Test
    public void maze03(){
        // 初始化地图
        int maze[][] = new int [8][7];

        // 无障碍物为0  有障碍物为1
        // 将第一行和最后一行设置障碍物
        System.out.println(maze.length);
        for (int i = 0; i < maze.length - 1; i++) {
            maze[0][i] = 1;
            maze[7][i] = 1;
        }

        // 将第一列和最后一列设置障碍物
        for (int i = 0; i < maze[0].length; i++) {
            maze[i][0] = 1;
            maze[i][6] = 1;

        }

        // 将第四行增加障碍
        maze[3][1] = 1;
        maze[3][2] = 1;

        // 测试回溯现象,增加墙
        maze[2][5] = 1;

        System.out.println("=====找路前遍历=====");
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }

        // 定义老鼠初始位置
        findway(maze,1,1,2);

        System.out.println("=====找路后遍历=====");
        for (int i = 0; i < maze.length; i++) {
            for (int j = 0; j < maze[i].length; j++) {
                System.out.print(maze[i][j] + "\t");
            }
            System.out.println();
        }

    }

    public boolean findway(int maze[][],int i,int j,int step){
        if (!(i>=0 && i<= maze.length && j >=0 && j<= maze[i].length)){
            return false;
        }
        // 0 无障碍
        // 1 有障碍
        // 2 通路
        // 3 死路

        if (maze[6][5] == 2){
            return true;
        }else if (maze[i][j] == 0){
            maze[i][j] = step;
            // 右下左上顺序
            if (findway(maze,i,j+1,2)){
                return true;
            }else if(findway(maze,i+1,j,2)){
                return true;
            }else if(findway(maze,i,j-1,2)){
                return true;
            }else if(findway(maze,i-1,j,2)){
                return true;
            }else {
                maze[i][j] = 3;
                return false;
            }
        }else {
            return false;
        }
    }
}

输出结果

8
=====找路前遍历=====
1	1	1	1	1	1	1	
1	0	0	0	0	0	1	
1	0	0	0	0	1	1	
1	1	1	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	0	0	0	0	0	1	
1	1	1	1	1	1	1	
=====找路后遍历=====
1	1	1	1	1	1	1	
1	2	2	2	2	3	1	
1	0	0	0	2	1	1	
1	1	1	0	2	2	1	
1	0	0	0	0	2	1	
1	0	0	0	0	2	1	
1	0	0	0	0	2	1	
1	1	1	1	1	1	1	

求出最短路径

这一块后续补充,需要学习图的遍历:深度优先和广度优先,弗洛伊德算法等

汉诺塔

汉诺塔

package com.hanoi;

import org.junit.Test;

/**
 * 汉诺塔
 *
 * @author wty
 * @date 2022/11/12 11:12
 */
public class Hanoi {
    @Test
    public void hanoi(){
            new Tower().move(3,'A','B','C');
        }
}

class Tower{
    /**
     * 汉诺塔的移动
     *
     * @param
     * @param: num 移动的个数
     * @param: a 塔
     * @param: b 塔
     * @param: c 塔
     * @return void
     * @date 2022/11/12 11:13
     * @author wty
     **/
    public void move(int num,char a,char b,char c){

        // 如果只有一个盘
        if (num == 1){
            System.out.println(a+"->"+c);
        }else {
            // 如果有多个盘,可以看成2个盘
            //(1)先移动上面所有的盘到B(需要借助C)
            move(num - 1,a,c,b);
            //(2)把最下面的盘,移动到C
            System.out.println(a+"->"+c);
            //(3)把B塔的所有盘,移动到C,借助A塔
            move(num - 1,b,a,c);
        }

    }

}

八皇后问题

八皇后问题

package com.queen;

import org.junit.Test;

/**八皇后
 *
 * @author wty
 * @date 2022/11/12 11:35
 */
public class EightQueen {
    @Test
    public void eightQueen(){
     int array[] = new int[8];
     put(array,0);
    }

    /***
     * 输出一维数组
     *
     * @param
     * @param: array
     * @return void
     * @date 2022/11/12 12:18
     * @author wty
     **/
    public void print(int array[]){
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
    }


    /**
     * 放置方式
     *
     * @param
     * @param: array 代表棋盘的每一行
     * @param: n 代表位置
     * @return boolean
     * @date 2022/11/12 11:37
     * @author wty
     **/
    public boolean findResult(int array[],int n){
        for (int i = 0; i < n; i++) {
            if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])){
                return false;
            }
        }
        return true;
    }

    /**
     * 放置棋子
     *
     * @param
     * @param: array 代表棋盘
     * @param: n 代表放置第n个位置
     * @return void
     * @date 2022/11/12 12:43
     * @author wty
     **/
    public void put(int array[],int n){
        if (n == array.length){
            print(array);
            return;
        }
        for (int i = 0; i < array.length; i++) {
            array[n] = i;
            // 只看0开头的分析即可
//            if (array[0] > 0){
//                break;
//            }
            if (findResult(array,n)){
                put(array,n+1);
            }
        }
    }



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心向阳光的天域

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值