回顾总结5

递归

自己调用自己

迷宫问题实例

思路

  1. 先创建迷宫,用二维数组表示,int[] [] map = new int[8] [7];
  2. 规定map数组中的元素值,0表示能走,1表示障碍物
  3. 设置障碍物
  4. 写递归方法,参数为map数组地图和初始位置(i,j)
  • 递归方法
    1. 外层判断,是否找到终点,是就返回true
    2. 不是的话,判断当前位置是否通路,是就标记走过
    3. 判断下一个位置,递归,重复所有步骤。

image-20210712175919920

public class Test { 
public static void main(String[] args) {
        //定义一个迷宫大小的二维数组
        int[][] map = new int[8][7];
        //设置障碍物1,第一行最后一行,行为固定值,列为变量,设置循环列变量
        for (int i = 0; i < 7; i++) {
            map[0][i] = 1;
            map[7][i] = 1;
        }
        //障碍物,第一列最后一列,列为固定值,行为变量,设置循环行变量
        for (int i = 0; i < 8; i++) {
            map[i][0] = 1;
            map[i][6] = 1;
        }
        //单独的障碍物
        map[3][1] = 1;
        map[3][2] = 1;

        T t = new T();
        t.findWay(map,1,1);

        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[i].length; j++) {
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }

    }
}
//递归所在的类。写递归方法
class T {
    //找迷宫只有两种结果,所以返回值选择布尔类型
    //参数有,迷宫的二维数组,当前的位置i和j
    public boolean findWay(int[][] map , int i , int j) {
        if(map[6][5] == 2){
            //这是一个返回值为布尔的方法
            //(6,5)是终点,如果把终点设置为2了,代表已经到终点了。退出循环,返回true
            return true;
        }else{
            if(map[i][j] == 0){
                //判断当前位置,是否能走,可以走就置为2,然后去下一个位置去判断
                map[i][j] = 2;
                //判断下一个位置,优先顺序为下右上左,不存在下一步就置为3.死路
                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] = 1,2,3。不能走,返回false
                return false;
            }
        }

    }
}

八皇后实例

思路分析

  1. 定义一维数组,下标表示行,值表示列
  2. 定义一个方法用来传递皇后的个数和建立数组
  3. 定义一个方法用来遍历值是否合法
  4. 定义一个方法对合法的判定
public class Queen {
    public static void main(String[] args) {
        Test test = new Test();
        test.queen(8);
        System.out.println(test.count);
    }
}

class Test {
    int[] arr;//定义一个数组,存放(8)皇后的数据
    int count = 0;//用来计数符合(8)皇后的数量
    int currentRow = 0;//数组的当前行

    public void queen(int n) {//传递是几皇后
        arr = new int[n];//建立一维数组
        check(n, currentRow);//传递一维数组的大小和一个定位当前数组行的变量
    }

    public void check(int n, int currentRow) {//检查所有符合条件的八皇后
        if (n == currentRow) {//如果当前行等于数组长度,说明所有行已经遍历完,得到一个八皇后
            for (int i = 0; i < arr.length; i++) {//将数组中的八皇后输出出来
                System.out.print(arr[i] + " ");
            }
            System.out.println();
            count++;//符合条件的八皇后数量+1
        } else {//还在遍历,判断皇后位置
            for (int i = 0; i < n; i++) {//八皇后是正方形,n既等于行数也等于列数。行数是随着数组下标自动增加的,i等于列数,n是总列数
                arr[currentRow] = i;//遍历每个列数,把值传递给数组然后判断是否符合条件
                if (judge(currentRow)) {//判断是否符合条件
                    check(n, currentRow + 1);//该行数符合条件,进行下一行的皇后判断
                }
            }
        }
    }

    public boolean judge(int currentRow) {//判断方法
        for (int i = 0; i < currentRow; i++) {//对该行的皇后,和前几行的皇后进行判断,是否在同一条直线(只有列,因为行是天然不相同的)或者斜线上
            if (arr[i] == arr[currentRow] ||//判断是否在同一列,数组的值就代表每一个皇后的列,i就是每个皇后的行值,把当前行之前的所有行的皇后遍历并比较
                    Math.abs(currentRow - i) == Math.abs(arr[currentRow] - arr[i])) {
                //判断是否在同一斜线。斜线有两条,斜率互为相反值,用绝对值可缩减为一次判断
                //根据x1-x2 是否等于y1-y2判断
                return false;//如果相同,说明直线上或斜线上有皇后,该位置不能放皇后
            }
        }
        return true;//for完整循环完毕出来之后,该位置可放皇后
    }
//在main方法里new本类对象的实例,然后调用queen()方法即可
}

作用域和变量

  1. 属性和局部变量可以重名,访问时遵循就近原则
  2. 同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名
  3. 属性生命周期较长,伴随着对象的创建而创建,销毁而销毁
  4. 局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁

修饰符

  • 全局变量可以加修饰符
  • 局部变量不能加修饰符

this关键字

细节:

  1. this关键字可以用来访问本类的属性、方法、构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员方法的语法:this.方法名(参数列表)
  4. 访问构造器的语法:this(参数列表)注意只能在构造器中调用另一个构造器。
  5. this不能在类定义的外部使用,只能在类定义的方法中使用

匿名对象

匿名只能用一次

因为没有名字,来引用它,所以只能在创建的时候知道它的位置并使用。用完之后就没办法调用它了。

new Test().count();
posted @ 2021-07-21 23:12  灰线  阅读(55)  评论(0)    收藏  举报