Reputation: 98
As the title implies, I'm having difficulty trying to recursively determine all the permutations of a given String
. The catch is that String
has to be given through a constructor of an object and then each of the permutations be found one by one. Basically, it has to work like this:
PermutationIterator iter = new PermutationIterator("eat");
while (iter.hasMorePermutations())
System.out.println(iter.nextPermutation());
Here is the code that I'm using but doesn't seem to work and I don't know how to fix it.
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;
}
}
Right now the program prints "eat" and "eta" but after that it through a StringIndexOutOfBounds
error off of the second stack. Any help with solving this is much appreciated.
Upvotes: 1
Views: 905
Reputation: 35
do a little change in your hasMorePermutation method as below to solved StringIndexOutOfBounds exception.
public boolean hasMorePermutations()
{
return pos < word.length() - 1;
}
Upvotes: 0
Reputation: 579
try this code - generates permutations for any given string
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));
}
}
}
Upvotes: 0
Reputation: 27946
Rather than just supplying the fix let me help diagnose your issue and then you can have a go at fixing it.
If you look carefully at your code you'll see that the hasMorePermutations
condition passes when pos == word.length() - 1
. That means nextPermutation
will be run when pos
is pointing to the last character in the string. But in that case when the third branch executes you increment pos
and then call word.substring(pos + 1)
. At that point pos + 1
will be larger than length of the string which will throw the exception.
I expect the fix will be fairly easy.
Upvotes: 2