JavaSE-回溯+自定义类栈实现Puzzle问题

Puzzle问题描述

如图有一个一维数组,上面的数字表示可以移动的步数,每个结点都有左右两个方向可以移动,例如第一个结点4,它只能往右移动4格到3的位置,而3左右都可以移动,要求是找到一条路径能够到达最后一个结点,该节点的值必定是0,如果能找到打印输出。手动测试完成后改为随机生成长度和元素值进行测试。

和迷宫问题类似,见迷宫问题,它变得更简单了。

先自定义一个类栈:

栈中用一个自定义的puzzleNode类型的一维数组存储结点信息,size为栈中有效元素个数,操作主要有入栈,出栈,取栈顶元素。

package com.puzzle;


import java.util.Arrays;
import java.util.EmptyStackException;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/21
 */
public class MyStack {
    private puzzleNode[] element;
    private int size;
    private static final int INITSIZE = 100;

    public MyStack(){
        element = new puzzleNode[INITSIZE];
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    private void ensureCapacity(){
        if(size == element.length){
            element = Arrays.copyOf(element,element.length+(element.length>>1));
        }
    }

    public void push(puzzleNode puzzleNode){
        ensureCapacity();
        element[size++] = puzzleNode;
    }

    public void pop(){
        if(size == 0){
            return;
        }
        size--;
    }

    public puzzleNode peek(){
        if(size == 0){
            throw new EmptyStackException();
        }
        return element[size-1];
    }
}

接下来定义结点类:

成员变量有结点的方向,东西四个方向,当前所在一维数组坐标,以及当前结点的value值。

package com.puzzle;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/21
 */
public class puzzleNode {
    private int value;
    public boolean way_east;
    public boolean way_west;
    private int index;

    public puzzleNode(int value, int index){
        this.value = value;
        this.index = index;
    }

    public puzzleNode(){

    }

    public int getIndex() {
        return index;
    }

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

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

接下来定义操作类,寻路,初始化操作等在此类中进行:

package com.puzzle;
import java.util.Arrays;
import java.util.Scanner;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/24
 */
public class Puzzle {
    private puzzleNode[] puzzleNodes;
    private int index;

    public Puzzle(int index) {
        this.index = index;
        puzzleNodes = new puzzleNode[index];
    }

    public void goPuzzle(){
        initValue();
        initWayState();
        MyStack stack = run();
        display(stack);
    }

    public void initValue(){
        Scanner in = new Scanner(System.in);
        System.out.println("input value:");
        for (int i = 0; i < 10; i++) {
            puzzleNodes[i] = new puzzleNode(in.nextInt(),i);
        }
    }

    private void initWayState(){
        for (int i = 0; i < 10; i++) {
            //右边能走
            if((i+puzzleNodes[i].getValue())<10){
                puzzleNodes[i].way_east = true;
            }
            //左边能走
            if((i-puzzleNodes[i].getValue())>=0){
                puzzleNodes[i].way_west = true;
            }
        }
    }

    //4 8 5 2 3 5 1 6 4 0
    public MyStack run(){
        MyStack stack = new MyStack();
        int i = 0;
        stack.push(puzzleNodes[0]);

        while(stack.getSize()!=0){
            //东边可走
            if(puzzleNodes[i].way_east){
                stack.push(puzzleNodes[i+puzzleNodes[i].getValue()]);
                puzzleNodes[i].way_east = false;
                i += puzzleNodes[i].getValue();
            }

            //西边可走
            else if(puzzleNodes[i].way_west){
                stack.push(puzzleNodes[i-puzzleNodes[i].getValue()]);
                puzzleNodes[i].way_west = false;
                i -= puzzleNodes[i].getValue();
            }

            //四路不通出栈
            else {
                stack.pop();
                if(stack.getSize()==0){
                    System.out.println("无路");
                    System.exit(0);
                }
                i = stack.peek().getIndex();
            }

            if(puzzleNodes[i].getValue() == 0){
                return stack;
            }
        }
        return stack;
    }

    public void display(MyStack stack){
        StringBuilder stringBuilder = new StringBuilder();
        int len = stack.getSize();
        for (int i = 0; i < len; i++) {
            stringBuilder.append(stack.peek().getValue()+"->");
            stack.pop();
        }
        System.out.println("存在路径");
        System.out.println(stringBuilder.reverse());
    }

    public void randomTest(int len){
        for (int i = 0; i < len-1; i++) {
            puzzleNodes[i] = new puzzleNode(1+(int)(Math.random()*(8+1)),i);
        }
        puzzleNodes[len-1] = new puzzleNode(0,len-1);
        System.out.println("Puzzle生成为:");
        for (int i = 0; i < len; i++) {
            System.out.print(puzzleNodes[i].getValue()+" ");
        }
        System.out.println();
        initWayState();
        MyStack stack = run();
        display(stack);
    }
}

 

测试类:

package com.puzzle;

import com.maze.Maze;

import java.util.ArrayList;
import java.util.Queue;
import java.util.Scanner;

/**
 * Description :
 * Created by Resumebb
 * Date :2020/10/24
 */
public class puzzleTest {

    public static void main(String[] args) throws Exception {
        //手动测试
//        Scanner in = new Scanner(System.in);
//        System.out.println("input size:");
//        Puzzle puzzle = new Puzzle(in.nextInt());
//          puzzle.goPuzzle();

        //随机生成
        int len = 10 + (int)(Math.random()*(5+1));
        Puzzle puzzle = new Puzzle(len);
        puzzle.randomTest(len);

    }
}

手动测试截图:

自动生成测试截图:

 

自动生成寻找一条存在的路径比较困难,我生成了好多次才找到一条。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值