Monday, September 17, 2012

All Permutations of a String (non-repetitive)



Design an algorithm to print all permutations of a
 *         string For simplicity, assume all characters are unique
 *
 *         Test String: abcdefg
 *
 *         Case “a” --> {a} Case “ab” --> {ab, ba} Case “abc”
 *
 *         This is the first “interesting” case If we had the answer to P(“ab”),
 *         how could we generate P(“abc”) Well, the additional letter is “c”, so
 *         we can just stick c in at every possible point That is:
 *
 *         merge(c, ab) --> cab, acb, abc merge(c, ba) --> cba, bca, bac
 *
 *         Algorithm: Use a recursive algorithm Generate all permutations of a
 *         string by “chopping off” the last character and generating all
 *         permutations of s[1… n-1] Then, insert s[n] into every location of
 *         the string
 *
 *         NOTE: Base Case and Build Algorithms often lead to natural recursive
 *         algorithms
The Best solution for this problem that I could find is ->
public static void permutation(String str) {
permutation("", str);
}
private static void permutation(String permutedString, String nonPermuted) {
int n =  nonPermuted .length();
if (n == 0)
System.out.println(permutedString + "--->>" + count++);
else {
for (int i = 0; i < n; i++)
permutation(permutedString +  nonPermuted .charAt(i),  nonPermuted .substring(0, i)
+  nonPermuted .substring(i + 1, n)); ............................................(1)
}
}
However, it doesn't take into consideration repetition of characters in the Strings. I will update it soon. however if you know the answer please feel free to leave a post here.
The complexity is O(N!) because there are N! possible permutations of a string with length N, so it’s optimal. I wouldn’t recommend executing it for strings longer than 10-12 characters though, it’ll take a long time. Not because it’s inefficient, but inherently there are just too many permutations.


------------------------------------------------------------------------------------------------------------
Found following two solutions for resolving repetitive problem 
1. Using the Treeset to hold all the premutations -> but that wont reduce the number of recursive calls
2. Using two lists which adds the permutedSting+charAt(i) and nonPermuted string simultaneously and checks to see if it the same generated pair at (1), if not than do the recursive call else ignore.

Global variables to the class -> static variables in this case ->


public static List<String> permutedStrAry = new ArrayList<String>();
public static List<String> nonpermutedStrAry = new ArrayList<String>();


public static void permutationRepititive(String permutedString, String str) {
int n = str.length();
if (n == 0) {
System.out.println(permutedString + "--->>" + count++);

} else {

for (int i = 0; i < n; i++) {
/**
* In order to remove the repetitive strings we say that if the
* permuted string if permutedString + str.charAt(i) and
* str.substring(0, i) + str.substring(i + 1, n) are the same
* for multiple values than we wont consider them.
*/
if ( (permutedStrAry.contains(permutedString + str.charAt(i)) && nonpermutedStrAry.contains(str.substring(0, i)    +    str.substring(i + 1, n)))) {
permutationRepititive(permutedString + str.charAt(i),
str.substring(0, i) + str.substring(i + 1, n));
nonpermutedStrAry.add(str.substring(0, i)
+ str.substring(i + 1, n));
permutedStrAry.add(permutedString + str.charAt(i));
}
}
}
}


No comments:

Post a Comment