java用栈实现Puzzle

题目:

初始正方形中的带圆圈的数字是可以移动到沿着行的其他正方形的标记。 在拼图的每个步骤,可以移动标记的正方形中由当前占据的整数指示的方格数。 标记可以沿着该行向左或向右移动,但可以不移动经过任一端。 例如,唯一合法的第一步是将标记向右移动三个方格,因为没有空间向左移动三个空格。拼图的目标是将标记移动到行的远端的0

要求

如果圆圈能够移动到最后0的位置,返回true,否则返回false

程序要适应任何大小的方格数,并且方格里的数字是随机的,范围是[1,9]。

输出圆圈走过的路径。

主要思路:

在puzzle类中,用num表示当前格子内的值,sign标记该格子走过的方向,-1表示向左移动,1表示向右移动,0表示没有移动过,2表示两边都移动过了。先将第一个值入栈,首先判断当前下标是否是最后一个格子的下标,即是否到达0,如果当前下标是最后一个格子的下标,到达最后的0,返回stack。否则根据sign的值判断其移动方向,如果是0,判断其能否进行左移和右移,可以的话,进行移动且入栈,并改变sign和index的值。如果不行,当前元素出栈。
这里我用lastIndex表示上一个入栈元素的下标。出栈之后,将index更新为lastIndex。
如果右移过即sign == 1 那么只需判断能否左移,如果可以,进行左移并 sign 赋值为2,否则,出栈,将index更新为lastIndex。
同样如果左移过即sign == -1 那么只需判断能否右移,如果可以,进行右移并 sign 赋值为2.否则,出栈,将index更新为lastIndex。

返回值我用的的Stack,如果栈为空或者栈的peek()元素不是0,那么表示没有成功。如果peek()元素值的是0,表示成功

puzzle.java代码

public class Puzzle {
    private int num;            //值
    private int sign;           //标记
    private int index;          //保存下标

    public Puzzle(int num,int index){
        this.num = num;
        this.index = index;
        sign = 0;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public int getSign() {
        return sign;
    }

    public void setSign(int sign) {
        this.sign = sign;
    }

}

Test.java代码

public class Test {                 //用栈实现puzzle
    public static void main(String[] args) {
        int[] arr = new int[]{4,8,5,2,3,5,1,6,4,0};
        Puzzle[] puzzle = new Puzzle[arr.length];
        for (int i=0;i<arr.length;i++){
            puzzle[i] = new Puzzle(arr[i],i);
            System.out.print(puzzle[i].getNum()+" ");
        }
        System.out.println();
        Stack<Puzzle> stack = run(puzzle);
        if(stack.isEmpty()){
            System.out.println("无解");
        }else{
            if (stack.peek().getNum() == 0){
                print(stack);
            }else{
                System.out.println("无解");
                print(stack);
            }
        }

    }
    public static void print(Stack<Puzzle> stack){
        System.out.println("走过的路径倒序输出为:");
        while(!stack.isEmpty()){
            System.out.println(stack.peek().getNum());
            stack.pop();
        }
    }

    private static Stack<Puzzle> run(Puzzle[] puzzles) {
        Stack<Puzzle> stack = new Stack();
        int index=0;                                //index代表当前数组下标
        if (puzzles[0].getNum() != 0){
            stack.push(puzzles[index]);
        }else{
            return stack;
        }
        while(!stack.isEmpty()){
            int num = stack.peek().getNum();
            int sign = stack.peek().getSign();
            int lastIndex = stack.lastElement().getIndex();        //上一个入栈元素的下标
            if (sign == 0){                         //没移动过
                if (puzzles.length-1 == index) {
                    return stack;
                }else if(puzzles.length-1 - index >= num){
                    //右移
                    stack.push(puzzles[index+num]);
                    puzzles[index].setSign(1);
                    index += num;
                }else if(index >= num){
                    //左移
                    stack.push(puzzles[index-num]);
                    puzzles[index].setSign(-1);
                    index -= num;
                }else{
                    stack.pop();
                    index = lastIndex;
                }
            }else if (sign == 1){                //右边移动过了
                if (index >= num){               //可以左移
                    stack.push(puzzles[index-num]);
                    puzzles[index].setSign(2);     //当前点两边都移动过了,置为2;
                    index -= num;
                }else{
                    stack.pop();
                    index = lastIndex;
                }
            }else if(sign == -1){                      //左移过了
                if (puzzles.length-1 - index >= num){      //可以右移
                    //右移
                    stack.push(puzzles[index+num]);
                    puzzles[index].setSign(2);              //当前点两边都移动过了,置为2;
                    index += num;
                }else{
                    stack.pop();
                    index = lastIndex;
                }
            }else{                                      //都移动过了
                return stack;
            }
        }
        return stack;
    }
}

            

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值