简体   繁体   中英

Generate permutations of strings with lengths 2 to N given N letters in Java

Given the following recursive Java method:

protected static void makeStringsList(List<String> strings, List<Character> letters) {
  if (letters.size() == 2) {
    strings.add(letters.get(0) + "" + letters.get(1));
    strings.add(letters.get(1) + "" + letters.get(0));
  }
  else {
    Character c = letters.remove(0);
    makeStringsList(strings, letters);
    List<String> tempList = new ArrayList<String>();
    for (String s : strings) {
      StringBuffer buffer = new StringBuffer(s);
      for (int index = 0; index < s.length() + 1; index++) {
        buffer.insert(index, c);
        tempList.add(buffer.toString());
        buffer = new StringBuffer(s);
      }
    }
    strings.addAll(tempList);
  }
}

Given N letters, the code above generates a list that contains permutations of strings that use all of those same N letters. For example, given (1, 2, 3), it generates:

  • 123
  • 132
  • 213
  • 231
  • 312
  • 321
It also adds strings with fewer than N letters to the list, but they're not exhaustive. Using the same example, 23 and 32 are also in the list, but 12, 21, 13, and 31 are not in the list.

I had originally created the method above for a kata I was previously working on here during my free time, and I want to modify it now so that I can make it more general purpose and return a list containing permutations of strings with lengths 2 to N given N letters. Is it possible to modify the method above to accomplish this task? Any tips? Your advice will be greatly appreciated!

I would like to help out with this problem.

I think the best way to go about this is to generate the power set of the set of characters given, and then find the set of combinations of strings that each set in the power set can generate.

List <String> allPermutationsOfSubsequences( Set <Character> chars ) {

    Set < Set <Character> > powerSetOfChars = generatePowerSet ( chars );

    List <String> permutations = new ArrayList <String> ();

    for (Set <Character> subsequence : powerSetOfChars)
        permutations.addAll( generatePermutations ( subsequence ) );

    return permutations;
}

Set <Set <Character>> generatePowerSet ( Set <Character> set ) {
    Set < Set <Character> > powerSet = new HashSet < Set <Character> > ();
    if (set.size() == 0) {
        powerSet.add(new HashSet <Character> ());
        return powerSet;
    }

    Character anElement = set.iterator().next();
    set.remove(anElement);

    for (Set <Character> subset : powerSet(set)) {
        Set <Character> setWithElement = new HashSet <Character> ();
        setWithElement.add(anElement);
        setWithElement.addAll(subset);
        powerSet.add(newSet);
        powerSet.add(subset);
    }

    set.add(anElement);

    return powerSets;
}

//Generates a list of permutations of the characters provided in the set.
List <String> generatePermutations ( Set <Character> chars );

The generatePowerSet method creates all the sets, so it also includes sets of size 0 and 1. You can remove those if you like, but the main idea is there.

Sample output: [3, 2, 1, 31, 13, 32, 23, 21, 12, 321, 312, 231, 213, 132, 123]

All you need to do is remove the ones of size 1.

For the full code, that has been compiled and has shown to work, just go here and try it yourself!

http://pastebin.com/P3YMmT2m

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM