查找C中长度增加的数字列表的排列

时间:2013-06-19 14:38:25

标签: c permutation

请考虑以下数字列表:0, 1, 2, 3

我试图找到长度为2,3和4的列表的所有排列。

(0, 1)
(0, 2)
(0, 3)
(1, 0)
(1, 2)
(1, 3)
(2, 0)
(2, 1)
(2, 3)
(3, 0)
(3, 1)
(3, 2)
(0, 1, 2)
(0, 1, 3)
(0, 2, 1)
(0, 2, 3)
(0, 3, 1)
(0, 3, 2)
(1, 0, 2)
(1, 0, 3)
(1, 2, 0)
(1, 2, 3)
(1, 3, 0)
(1, 3, 2)
(2, 0, 1)
(2, 0, 3)
(2, 1, 0)
(2, 1, 3)
(2, 3, 0)
(2, 3, 1)
(3, 0, 1)
(3, 0, 2)
(3, 1, 0)
(3, 1, 2)
(3, 2, 0)
(3, 2, 1)
(0, 1, 2, 3)
(0, 1, 3, 2)
(0, 2, 1, 3)
(0, 2, 3, 1)
(0, 3, 1, 2)
(0, 3, 2, 1)
(1, 0, 2, 3)
(1, 0, 3, 2)
(1, 2, 0, 3)
(1, 2, 3, 0)
(1, 3, 0, 2)
(1, 3, 2, 0)
(2, 0, 1, 3)
(2, 0, 3, 1)
(2, 1, 0, 3)
(2, 1, 3, 0)
(2, 3, 0, 1)
(2, 3, 1, 0)
(3, 0, 1, 2)
(3, 0, 2, 1)
(3, 1, 0, 2)
(3, 1, 2, 0)
(3, 2, 0, 1)
(3, 2, 1, 0)

我需要在C中实现这一点,但我找到的所有算法[1,2]只给出了长度等于数字列表长度的排列,即只有(0, 1, 2, 3)中的结果。挡在上面。将长度从4减少到3只给出列表0, 1, 2的排列。

我现在可以使用itertools.permutation在Python中实现我想要的功能,如下所示。

import itertools

MaxN = 4

for Length in range(2, MaxN + 1):
    for perm in itertools.permutations(Indices, Length):
        print perm

有关如何在C中实现此功能的任何建议将不胜感激。

[1] http://rosettacode.org/wiki/Permutations#C

[2] http://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/

4 个答案:

答案 0 :(得分:2)

您可以稍微修改[2]来执行此操作:

/* Function to print permutations of string
   This function takes three parameters:
   1. String
   2. Starting index of the string
   3. Ending index of the string.
   4. Length of permutation */
void permute(char *a, int i, int n, int m) 
{
   int j; 
   if (i == m)
   {
       char temp = *(a+i);
       *(a+i) = '\0';
       printf("%s\n", a);
       *(a+i) = temp;
   }
   else
   {
       for (j = i; j <= n; j++)
       {
          swap((a+i), (a+j));
          permute(a, i+1, n, m);
          swap((a+i), (a+j)); //backtrack
       }
   }
} 

会像这样使用:

char a[] = "0123";  
for (int i = 2; i <= 4; i++)
    permute(a, 0, 3, i);

它提供与Python实现相同的结果。

答案 1 :(得分:1)

你可以使用combination generating algorithm吐出C(n,k)组合序列来增加外环中的k,并应用P(k,k)置换算法来产生序列每种组合的排列。

c = empty_combination();
for (k = 0; k <= n; ++k) {
    do {
        c = next_combination(c, sequence, k);
        p = empty_permutation();
        do {
            p = next_permutation(p, c);
            print_permutation(p);
        } while (! is_empty_permutation(p));
    } while (! is_empty_combination(c));
}

答案 2 :(得分:0)

在C ++中完成它非常简单。使用(next_permutation())方法。

http://www.cplusplus.com/reference/algorithm/next_permutation/

答案 3 :(得分:0)

这是一个生成所有子集的迭代方法!
子集总数为2 ^ n - 1
所以它生成所有长度的子集 如果你想要特定长度的子集,只需添加一个计数器并检查你是否打印特定长度。

main(){
int a[]={0,1,2,3};
int n=pow(2,4) - 1;
for(int i=0;i<=n;i++){
    int p = i;
    int l=0;
    while(p){
        if(p%2==1)
            printf("%d",a[l]);
        p>>=1;
        l++;
    }
    printf("\n");
}
}