Optimal algorithm for generating all combinations (order of letter matters) of a word

拈花ヽ惹草 提交于 2019-12-08 11:46:17

问题


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.


回答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




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/17693581/optimal-algorithm-for-generating-all-combinations-order-of-letter-matters-of-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!