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);
}
}
手动测试截图:
自动生成测试截图:
自动生成寻找一条存在的路径比较困难,我生成了好多次才找到一条。