0

I am looking for an algorithm (optimal) for generating all possible combinations of a word.

For example:

Given the word love, the following would be outputted:

Generated words: 24 elov elvo eolv eovl evlo evol leov levo loev love lveo lvoe oelv oevl olev olve ovel ovle velo veol vleo vloe voel vole

Given the word bell (note about the repeating l), the following would be outputted:

Generated words: 12 bell blel blle ebll elbl ellb lbel lble lebl lelb llbe lleb

I have my own algorithm in generating all combinations of a given word. I am basically implementing a combination tree. This is so far more comprehensive yet it consumes a lot of space and time.

Lynnell Neri
  • 473
  • 1
  • 9
  • 21
  • What is combination tree?A recursive generation of combinations? – Aravind Jul 17 '13 at 07:31
  • Maybe you want to sort the word lexicographically and apply some "nextWord" function while possible? – Herokiller Jul 17 '13 at 07:31
  • I think the more appropriate term is "multiset permutation". https://en.wikipedia.org/wiki/Permutation – rliu Jul 17 '13 at 07:32
  • This question seems promising: http://stackoverflow.com/questions/3467914/is-there-an-algorithm-to-generate-all-unique-circular-permutations-of-a-multiset. Note that it doesn't generate all permutations, it generates them up to cyclic isomorphism (<- I made that up). So after you have all of those "distinct cyclic arrangements" you'll have to rotate it to generate the permutations. But that extra step is fast (linear). So if Sawada's algorithm is fast, then the whole algorithm will be fast. – rliu Jul 17 '13 at 07:42

3 Answers3

1

One can generate permutations (excluding the duplicate constraint) by, for each character, swapping that character with the first character and recursing by excluding the first character.

Now if we want to exclude duplicates, we simply need to make sure we don't put the same character in the first position twice. Doing this can be done by sorting the characters (so the duplicate characters are next to one another) and skipping over any character that's the same as the one before it or the same as the character at the target position.

Java code: (derived from a basic permutation generator)

import java.util.Arrays;
import java.util.Scanner;

public class NewMain
{
   public static void main(String[] args)
   {
      Scanner sc = new Scanner(System.in);
      System.out.println("Enter the string:");
      String s = sc.nextLine();
      char[] c = s.toCharArray();
      Arrays.sort(c);

      System.out.println("Here are all the permutations:");
      NewMain.c = c;
      count = 0;
      permutation(0);
      System.out.println("Number of permutations = " + count);
   }

   static char[] c;
   static int count;

   static void swap(int pos1, int pos2)
   {
      char temp = c[pos1];
      c[pos1] = c[pos2];
      c[pos2] = temp;
   }

   public static void permutation(int start)
   {
      if (start == c.length)
      {
         System.out.println(c);
         count++;
      }

      for (int i = start; i < c.length; i++)
      {
         if (i == start || (c[i] != c[i-1] && c[i] != c[start]))
         {
            swap(start, i);
            permutation(start + 1);
            swap(start, i);
         }
      }
   }
}

Test.

Now this is still not particularly efficient if there are too many duplicate characters. One way I can think of to improve on this is by having a count for each character (maybe in the form of a linked-list (a linked-list of counts) so we can quickly remove counts that have reached 0, and insert them back afterwards) and, similar to above, we generate characters from left to right, skipping over duplicates by only processing each count once at each recursive step.

Community
  • 1
  • 1
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
1
  1. Take the total number of letters in the word, n, and find n!.
  2. Count the number of occurrences of each letter. For each letter that repeats more than once, divide by the (number of repetition)!

Example: 'banana'

2 n's, 3 a's, 6 total letters

Answer = 6!/(2!*3!) = 60

Guy Blanc
  • 833
  • 8
  • 14
0

After a long time, I've finally got an answer to my question. I used PHP as my programming language (because it's my choice and not of anything else) and I used Pear Package: Math Combinatorics.

Lynnell Neri
  • 473
  • 1
  • 9
  • 21