Now that's an interesting twist towards acquiring string permutations and is a lot easier said than done. Never the less it is relatively simple to accomplish if you actually had a method that would give you the desired permutations based on a provided min/max length value for each permutation and I'm sure StackOverflow alone has many many code examples of such.
Generally permutations are done on simple strings like "abc"
rather than elements contained within a single character/string collection of some sort like {'a', 'b', 'c'}
or {"a", "b", "c"}
. In order to effectively acquire your desired permutations you will need to convert your ArrayList elements into a string so that {"a", "b", "c"}
will become "abc"
. It's pointless to continue things within a collection unless each element actually contains more than one string character therefore converting the collection to a string makes sense.
To start with you need a method that will carry out string permutations and I'm certain there are plenty to go around here in StackOverflow. In any case I'm going to provide you with my rendition of a permutation method which allows you to supply a String, provide the desired character length of each permutation, and to remove duplicates (or not). The method only accepts a string so as to keep the method flexible. It does however return an ArrayList of String to which you can of course change to return whatever you like by doing a little modification to the code. If you do change the code, remember that the method is recursive:
/**
* This method will generate all possible permutations of the supplied input
* string and return all those permutations within an String
* ArrayList.<br><br>
*
* @param inputString (String) The string to acquire permutations
* from.<br>
*
* @param length (Integer) The desired min/max string length of
* returned permutations. In other words, if you only
* want all permutations consisting of 3 characters
* then supply the number 3. If you want all possible
* permutations to be returned then supply the number
* 0.<br>
*
* @param removeDuplicates (Boolean) Supply boolean true to ensure there will
* be no duplicate permutations within the returned ArrayList. Supply false if
* duplicates are desired. You can get duplicate permutations if there are
* duplicate characters within the supplied input string, for example:<pre>
*
* "aabbcc"
*
* can return these permutations:
*
* a, a, b, b, c, c 1 Character Permutations. See the Duplicates?
*
* aa, ab, ac, aa, ab, ac, 2 Character Permutations
* ba, bb, bc, ba, bb, bc, See the Duplicates?
* ca, cb, cc, ca, cb, cc
*
* aab, aac, aba, abb, abc, 3 Character Permutations
* aca, acb, acc, aab, aac, See the Duplicates?
* aba, abb, abc, aca, acb,
* acc, baa, bab, bac, bba,
* bbc, bca, bcb, bcc, baa,
* bab, bac, bba, bbc, bca,
* bcb, bcc, caa, cab, cac,
* cba, cbb, cbc, cca, ccb,
* caa, cab, cac, cba, cbb,
* cbc, cca, ccb
*
* However if boolean true is supplied to remove duplicates the results would
* be:
*
* a, b, c 1 Character Max Permutations. No Duplicates.
*
* aa, ab, ac, ba, bb, bc, 2 Character Max Permutations
* ca, cb, cc No Duplicates
*
* aab, aac, aba, abb, abc, 3 Character Max Permutations
* aca, acb, acc, baa, bab, No Duplicates
* bac, bba, bbc, bca, bcb,
* bcc, caa, cab, cac, cba,
* cbb, cbc, cca, ccb</pre>
*
*
* @param recursiveResult (String) FOR INTERNAL RECURSIVE USE ONLY! DO NOT
* SUPPLY A ARGUMENT HERE!<br>
*
* @return (String ArrayList)
*/
public ArrayList<String> getPermutations(String inputString, final int length,
boolean removeDuplicates, String... recursiveResult) {
String currentResult = "";
if (recursiveResult.length > 0) {
currentResult = recursiveResult[0];
}
//Convert the inputString to a ArrayList of characters...
ArrayList<Character> possibleChars = new ArrayList<>(inputString.length());
for (int i = 0; i < inputString.length(); i++) {
possibleChars.add(inputString.charAt(i));
}
ArrayList<String> result = new ArrayList<>(possibleChars.size());
for (char append : possibleChars) {
String permutation = currentResult + append; //create a new string with an additional character
if (permutation.length() == length || length == 0) {
result.add(permutation); //add the permutation to the result
}
if (possibleChars.size() > 0) {
//make a new list with the appendable characters
ArrayList<Character> possibleCharsUpdated = (ArrayList) possibleChars.clone();
//from that list, exclude the character we just appended
possibleCharsUpdated.remove(new Character(append));
//Convert the new character ArrayList to a String
//of characters for the recursion...
String passToRecursion = "";
for (int i = 0; i < possibleCharsUpdated.size(); i++) {
passToRecursion += possibleCharsUpdated.get(i);
}
//merge the result of a recursive call of this method and the result we already had
result.addAll(getPermutations(passToRecursion, length, true, permutation));
}
}
// Remove duplicates if desired...
// LinkedHashSet doesn't allow for Duplicates
// and automatically removes them.
if (removeDuplicates) {
ArrayList<String> tmpArray = new ArrayList<>(new LinkedHashSet<>(result));
result.clear();
result.addAll(tmpArray);
tmpArray.clear();
}
return result;
}
Now to get the results you desire from what you have provided, it would go something like this:
// Create String ArrayList
ArrayList<String> strings = new ArrayList<>();
strings.add("a"); strings.add("b"); strings.add("c");
// Convert ArrayList to a simple string
String stringToPermutate = String.join("", strings);
// Hold the number of elements within the strings ArrayList
int n = strings.size();
// Counter for while loop condition which will
// ultimately determine the Permutation Character
// Length for each iteration within the WHILE loop.
int k = 1;
// Prepare to build a result string that will hold
// the result from each call to the getPermutations
// method (which by the way is a recursive method).
StringBuilder sol = new StringBuilder();
while (k <= n) {
// Call method to permutate our simple string based
// on the Permutation Character Length stipulated by k
ArrayList<String> permutations = getPermutations(stringToPermutate, k, true);
// Convert ArrayList to a comma (, ) delimited string
String listToString = String.join(", ", permutations);
// Ternary used here instead of IF/ELSE
sol.append(sol.toString().equals("") ? listToString : ", " + listToString);
// Increment counter
k++;
}
// Split the contents of sol into a string Array
String[] solution = sol.toString().split(", ");
// Print solution String Array to Console window.
System.out.println(Arrays.toString(solution));
And here is what you should end up with displayed within the Console Window:
[a, b, c, ab, ac, ba, bc, ca, cb, abc, acb, bac, bca, cab, cba]