我有一个问题是列出重复的排列,保持这种“风格”,使用递归函数。
在2D数组中有例如2个元素“AB”和“CD”:
Element[0][0] = A; Element[0][1] = B; // AB
Element[1][0] = C; Element[1][1] = D; // CD
我想通过重复n个元素(在本例中为2)将所有可能的排列组合成k个组(在本例中为2)并将它们保存到新的2D数组中 例如:
Permutation[0][0] = AB; Permutation[0][1] = AB; // 1°: AB,AB
Permutation[1][0] = AB; Permutation[1][1] = CD; // 2°: AB,CD
Permutation[2][0] = CD; Permutation[2][1] = AB; // 3°: CD,AB
Permutation[3][0] = CD; Permutation[3][1] = CD; // 4°: CD,CD
元素和置换必须是二维数组。 我尝试过这种方式,但它只能将2个元素的排列分成两组并且我被锁定了:
int i_perm = 0;
int i_element = 0;
int k_tot = 2; // number of groups
[...]
calcPerms(2);
[...]
private void calcPerms(int k)
{
if (k == 0)
{
if(i_perm + 1 < i_perm)
i_perm++;
i_element=0;
}
else
{
for (int i = 0; i < element.length; i++)
{
Permutation[i_perm][i_element][0] = Element[i][0];
Permutation[i_perm][i_element][1] = Element[i][1];
if(i_element + 1 < k_tot)
i_element++;
calcPerms(k - 1);
if(i_perm >= i_perm)
i_perm--;
Permutation[i_perm][i_element][0] = Element[i][0];
Permutation[i_perm][i_element][1] = Element[i][1];
if(i_element + 1 < k_tot)
i_element++;
}
}
}
如上所述,这只适用于2个组中2个元素的排列,正确返回:
ABAB,ABCD,CDAB,CDCD。
确实如果我放3个元素(第3个元素是EF),它会返回:
ABAB,ABCD,CDEF,EFAB,ABCD,CDEF,EFAB,ABCD,EFEF
而不是:
ABAB,ABCD,ABEF,CDAB,CDCD,CDEF,EFAB,EFCD,EFEF
我怎样才能得到我想要的东西?谢谢大家的帮助,并为我糟糕的英语道歉
答案 0 :(得分:0)
您需要的是Heap's Algorithm
在链接的维基百科页面中有一个清晰的伪代码实现。
非递归版本看起来像这样
procedure generate(n : integer, A : array of any):
c : array of int
for i := 0; i < n; i += 1 do
c[i] := 0
end for
output(A)
i := 0;
while i < n do
if c[i] < i then
if i is even then
swap(A[0], A[i])
else
swap(A[c[i]], A[i])
end if
output(A)
c[i] += 1
i := 0
else
c[i] := 0
i += 1
end if
end while