我正在寻找一种算法(最佳)来生成一个单词的所有可能组合。
例如:
鉴于爱这个词,将输出以下内容:
生成的单词:24 elov ELVO eolv eovl 器EV10 EVOL leov 左旋 loev 爱 lveo lvoe oelv oevl OLEV olve OVEL ovle VELO VEOL vleo vloe voel 田鼠
如果单词 bell (注意重复的 l ),将输出以下内容:
生成的单词:12 钟 BLEL blle ebll ELBL ellb lbel lble LEBL lelb llbe lleb
我有自己的算法来生成给定单词的所有组合。我基本上实现了一个组合树。这是迄今为止更全面,但它消耗了大量的空间和时间。
答案 0 :(得分:1)
可以为每个字符生成排列(不包括重复约束),用第一个字符交换该字符,并通过排除第一个字符进行递归。
现在,如果我们想要排除重复项,我们只需要确保我们不会将相同的字符放在第一个位置两次。这样做可以通过对字符进行排序(使重复的字符彼此相邻)并跳过任何与之前的字符相同或与目标位置的字符相同的字符来完成。
Java代码:(派生自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);
}
}
}
}
如果太多多个重复字符,现在仍然不是特别有效。我可以想到改进的一种方法是对每个字符进行计数(可能是以链表(计数链表)的形式),这样我们就可以快速删除已经达到0的计数,然后插入它们之后回来),与上面类似,我们从左到右生成字符,跳过重复项,只在每个递归步骤处理一次计数。
答案 1 :(得分:1)
实施例: '香蕉'
2个,3个,6个字母
答案= 6!/(2!* 3!)= 60
答案 2 :(得分:0)
经过很长一段时间,我终于得到了一个问题的答案。我使用PHP作为我的编程语言(因为这是我的选择而不是其他任何东西)而且我使用了Pear Package: Math Combinatorics。