可以通过为每个字符交换该字符与第一个字符并通过排除第一个字符来递归来生成置换(不包括重复约束)。
现在,如果我们想排除重复项,我们只需确保我们不会将相同的字符放在第一个位置两次。这样做可以通过对字符进行排序(使重复字符彼此相邻)并跳过与之前的字符相同的字符或与目标位置上的字符相同的字符来完成。
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);
}
}
}
}
Test。
现在如果还有太许多重复字符,这仍然不是特别有效。我可以想到的一种改进方法是对每个字符进行计数(可能是链接列表(链接列表的计数)),以便快速删除已达到0的计数并插入它们之后回来),和上面类似,我们从左到右生成字符,在每个递归步骤中只处理每个计数一次,跳过重复项。
什么是组合树?递归生成组合? – Aravind
也许你想按字典顺序排序并在可能的情况下应用一些“nextWord”功能? – Herokiller
我认为更适合的术语是“多重排列”。 https://en.wikipedia.org/wiki/Permutation – rliu