public class Utilities {
/**
* Returns a list of all permutations of the given string
*
* @param str the string that may or may not contain variable references
* @param vtable the map of variables
* @return a collection containing all permutations of the given string
*/
public static Collection<String> getPermutations(String str, Map<String, Collection<String>> vtable) {
// Check if the string contains variables or not (the $ sign)
if (str.contains(Lang.VAR_ID)) {
// Check if the variable starts at the first index or not
int index = str.indexOf(Lang.VAR_ID);
if (index > 0) {
// If the variable did not start at the first index separate the parts with and
// without the variables
String withVars = str.substring(index);
str = str.substring(0, index);
// Combine the string with whatever was in the variables
return combine(Arrays.asList(str), createPermutations(withVars, vtable));
}
return createPermutations(str, vtable);
}
// If no variables existed, return a collection containing the given string
return Arrays.asList(str);
}
/**
* Basically, what this method does is to generate a collection of strings containing all possible permutations,
* or combinations if you prefer, of the variables in them
*
* @param str the string to parse
* @param vtable the map containing the variables
*/
private static Collection<String> createPermutations(String str, Map<String, Collection<String>> vtable) {
// Get the smallest valid index of an array
int index = minIndex(str.indexOf(Lang.VAR_ID, 1),
str.indexOf(Lang.SPACE));
// If the returned index is not -1 then get the variable and combine with the result from a recursive call
// to getPermutations
if (index > -1) {
String next = str.substring(index);
str = str.substring(0, index);
return combine(vtable.get(str), getPermutations(next, vtable));
}
else {
// If the index was -1 then the entire string van be assumed to be a variable name
return vtable.get(str);
}
}
// NOTE: Dont worry about the methods bellow this point, I just included them to make it clear where they come from since they are used by the relevant methods
/**
* Returns the smallest valid index for a string or -1, if none of
* them where valid
*
* @param a one index
* @param b another index
* @return the smallest valid index or -1 if no index was valid
*/
public static int minIndex(int a, int b) {
if (a < 0)
return (b < 0) ? -1 : b;
else if (b < 0)
return (a < 0) ? -1 : a;
return Math.min(a, b);
}
/**
* Combines the left and right collections by adding each string in the right collection to each and every
* string in the left collection
*
* @param left a collection of strings
* @param right a collection of strings
* @return the collection that resulted from the combination
*/
private static Collection<String> combine(Collection<String> left, Collection<String> right) {
Collection<String> combined = new ArrayList<>(left.size() + right.size());
for (String ls : left) {
for (String rs : right) {
combined.add(ls + rs);
}
}
return combined;
}
}