正如标题所暗示的那样,我在尝试以递归方式确定给定String
的所有排列时遇到了困难。问题是String
必须通过对象的构造函数给出,然后逐个找到每个排列。基本上,它必须像这样工作:
PermutationIterator iter = new PermutationIterator("eat");
while (iter.hasMorePermutations())
System.out.println(iter.nextPermutation());
以下是我使用的代码,但似乎无法正常使用,我也不知道如何修复它。
public class PermutationIterator {
private String word;
private int pos;
private PermutationIterator tailIterator;
private String currentLetter;
public PermutationIterator(String string) {
word = string;
pos = 0;
currentLetter = string.charAt(pos) + "";
if (string.length() > 1)
tailIterator = new PermutationIterator(string.substring(pos + 1));
}
public String nextPermutation() {
if (word.length() == 1) {
pos++;
return word;
} else if (tailIterator.hasMorePermutations()) {
return currentLetter + tailIterator.nextPermutation();
} else {
pos++;
currentLetter = word.charAt(pos) + "";
String tailString = word.substring(0, pos) + word.substring(pos + 1);
tailIterator = new PermutationIterator(tailString);
return currentLetter + tailIterator.nextPermutation();
}
}
public boolean hasMorePermutations() {
return pos <= word.length() - 1;
}
}
现在节目打印&#34;吃&#34;和&#34; eta&#34;但之后它通过第二个堆栈的StringIndexOutOfBounds
错误。任何帮助解决这个问题都非常感谢。
答案 0 :(得分:2)
不是仅提供修复程序,而是让我帮助诊断您的问题,然后您就可以开始修复它。
如果仔细查看代码,您会发现hasMorePermutations
时pos == word.length() - 1
条件已经过去了nextPermutation
。这意味着当pos
指向字符串中的最后一个字符时,将运行pos
。但是在第三个分支执行的情况下,您递增word.substring(pos + 1)
然后调用pos + 1
。此时{{1}}将大于将抛出异常的字符串的长度。
我希望修复程序相当容易。
答案 1 :(得分:0)
尝试此代码 - 为任何给定字符串生成排列
package testing;
import java.util.ArrayList;
import java.util.List;
public class Permutations {
/*
* You will get n! (factorial) - permutations from this
*
* Just like this Example: abc (3! = 6 permutations) [abc acb bac bca cab
* cbc]
*/
static String str = "abcd";
static char[] ch = str.toCharArray();
static List<String> s1 = new ArrayList<>();
static List<String> s2 = new ArrayList<>();
public static void main(String[] args) {
// s1 - list stores initial character from the string
s1.add(String.valueOf(ch[0]));
// recursive loop - char by char
for (int k = 1; k < ch.length; k++) {
// adds char at index 0 for all elements of previous iteration
appendBefore(s1, ch[k]);
// adds char at last index for all elements of previous iteration
appendAfter(s1, ch[k]);
// adds char middle positins like a^b^C - if prev list stores
// elements
// whose size() is 3 - then it would have 2 positions fill
/*
* say d is next char - d should be filled in _^_^_ _ positions are
* previous permuions for 3 chars a,b,c(i.e 6 permutations
*/
appendMiddle(s1, ch[k], k);
// for every iteration first clear s1 - to copy s2, which contains
// previous permutatons
s1.clear();
// now copy s2 to s1- then clear s2
// - this way finally s2 contains all the permutations
for (int x = 0; x < s2.size(); x++) {
s1.add(s2.get(x));
}
System.out.println(s1);
System.out.println(s1.size());
s2.clear();
}
}
private static void appendMiddle(List str, char ch, int positions) {
for (int pos = 1; pos <= positions - 1; pos++) {
for (int i = 0; i < str.size(); i++) {
s2.add(str.get(i).toString().substring(0, pos) + String.valueOf(ch)
+ str.get(i).toString().substring(pos, str.get(i).toString().length()));
}
}
}
private static void appendBefore(List str, char ch) {
for (int i = 0; i < str.size(); i++) {
s2.add(String.valueOf(ch) + str.get(i));
}
}
private static void appendAfter(List str, char ch) {
for (int i = 0; i < str.size(); i++) {
s2.add(str.get(i) + String.valueOf(ch));
}
}
}
答案 2 :(得分:0)
在你的hasMorePermutation方法中做一点改动,如下所示,解决StringIndexOutOfBounds异常。
public boolean hasMorePermutations()
{
return pos < word.length() - 1;
}