【发布时间】:2018-07-14 16:47:53
【问题描述】:
我想我已经找到了按字母顺序排列字符串(ABCDE 以任意顺序)的最小移动量。
有一些条件必须遵守:
- 要么交换第一个和第二个元素 (
b),要么: - 将字符串右移一步 (
s)
但是,我也在尝试打印出我用来到达最短路径的动作。
例如,如果我输入BECAD,我会得到Minimum step used: 7,但我也想打印bsssbsb。
现在我的 StringBuilder 一直在追加所有可能的动作。任何帮助,将不胜感激。
public static void main(String[] args) {
String s = "BECAD";
int step = 0;
System.out.println("Minimum step used: " + robot(s, step));
}
public static int robot(String s, int step) {
StringBuilder sb1 = new StringBuilder();
Queue<State> leftQ = new LinkedList<>();
Queue<State> rightQ = new LinkedList<>();
State nodeLeft = new State(s, step, 0, sb1);
State nodeRight = new State(s, step, 0, sb1);
//while we havent reached ABCDE continue until one of them reaches
while(!(nodeLeft.s.equals("ABCDE")) && !(nodeRight.s.equals("ABCDE"))) {
// first loop we will always enter the first condition.
if(nodeLeft.previousMove == 0 || nodeRight.previousMove == 0) {
leftQ.offer(new State(nodeLeft.s.substring(1, 2) + nodeLeft.s.substring(0, 1) + nodeLeft.s.substring(2, 5), nodeLeft.currentSteps + 1, nodeLeft.previousMove = 1, nodeLeft.allMoves.append("b")));
rightQ.offer(new State(nodeLeft.s.substring(4, 5) + nodeLeft.s.substring(0, 4), nodeRight.currentSteps + 1, nodeRight.previousMove + 2, nodeRight.allMoves.append("s")));
// there are two queues, left and right. first we swap the 1st element with the 2nd element and push it to the leftQ. The other one be will shift the string one step left and push it to the rightQ.
} else if(nodeLeft.previousMove == 1 || nodeRight.previousMove == 1) {
leftQ.offer(new State(nodeLeft.s.substring(4, 5) + nodeLeft.s.substring(0, 4), nodeLeft.currentSteps + 1, nodeLeft.previousMove = 2, nodeLeft.allMoves.append("s")));
rightQ.offer(new State(nodeRight.s.substring(4, 5) + nodeRight.s.substring(0, 4), nodeRight.currentSteps + 1, nodeRight.previousMove = 2, nodeRight.allMoves.append("s")));
} else if(nodeLeft.previousMove == 2 || nodeRight.previousMove == 2) {
leftQ.offer(new State(nodeLeft.s.substring(1, 2) + nodeLeft.s.substring(0, 1) + nodeLeft.s.substring(2, 5), nodeLeft.currentSteps + 1, nodeLeft.previousMove = 1, nodeLeft.allMoves.append("b")));
leftQ.offer(new State(nodeLeft.s.substring(4, 5) + nodeLeft.s.substring(0, 4), nodeLeft.currentSteps + 1, nodeLeft.previousMove = 2, nodeLeft.allMoves.append("s")));
rightQ.offer(new State(nodeRight.s.substring(1, 2) + nodeRight.s.substring(0, 1) + nodeRight.s.substring(2, 5), nodeRight.currentSteps + 1, nodeRight.previousMove = 1, nodeRight.allMoves.append("b")));
rightQ.offer(new State(nodeRight.s.substring(4, 5) + nodeRight.s.substring(0, 4), nodeRight.currentSteps + 1, nodeRight.previousMove = 2, nodeRight.allMoves.append("s")));
// to avoid endless loop i check the previous move. If i swapped previously i must shift one step left.
}
nodeLeft = leftQ.poll();
nodeRight = rightQ.poll();
// i continue to poll from both the queues to see which one reaches ABCDE first.
// Since i am building something like a binary tree on the width
// eventually one of the nodes will reach first. Then i set the other to a max value since it never finished it search.
}
if(!(nodeLeft.s.equals("ABCDE"))) {
nodeLeft.currentSteps = Integer.MAX_VALUE;
}
if(!(nodeRight.s.equals("ABCDE"))) {
nodeRight.currentSteps = Integer.MAX_VALUE;
}
return Math.min(nodeLeft.currentSteps, nodeRight.currentSteps);
// here i return the minimum amount of steps taken to achieve my goal
}
public class State {
public String s;
public int currentSteps;
public int previousMove;
public StringBuilder allMoves;
public State(String s, int currentSteps, int previousMove, StringBuilder allMoves) {
this.s = s;
this.currentSteps = currentSteps;
this.previousMove = previousMove;
this.allMoves = allMoves;
}
}
【问题讨论】:
-
我试过调试你的程序,但没有多大意义。可以加一些cmets吗?
-
@GalAbra 添加了一些 cmets。请看看它是否有帮助。
-
我仍然没有完全理解那里发生了什么,但我可以告诉你这不是递归,因为
State不会调用自己。
标签: java string sorting recursion minimum