排列组合的实现

2017-09-07  本文已影响0人  Joe_HUST

C语言中的排列和组合在实际的应用中使用广泛。
排列算法
*字典序法
*递增进位制数法
*递减进位制数法
*邻位对换法
*递归法


1.字典序法

2. 递归法

int  n = 0;//记录排列的数量
void swap(int *a,int *b)
{
    int m;
    m = *a;
    *a = *b;
    *b = m;
}
void Permutation(int *a,int start,int end)
{
    int i;
    if( start > end )
    {
        for (i = 0; i <= end; ++i)
        {
            printf("%d",a[i]);
        }
        printf("\n");
        ++n;
    }
    else
    {
        for (i = start; i <=end; ++i)
        {
            swap(&a[start],&a[i]);
            Permutation(a,start+1,end);
            swap(&a[start],&a[i]);
        }
    }
}

3. 组合算法

/// 求从数组a[1..n]中任选m个元素的所有组合.
/// a[1..n]表示候选集,n为候选集大小,n>=m>0。
/// b[1..M]用来存储当前组合中的元素(这里存储的是元素下标),
/// 常量M表示满足条件的一个组合中元素的个数,M=m,这两个参数仅用来输出结果。
void Combine2(int *a,int n,int m,int *b,const int M)
{
    for (int i = n; i >= m; --i)
    {
        b[m-1] = i-1;
        if(m > 1)
        {
            Combine2(a,i-1,m-1,b,M);
        }
        else
        {
            for (int j = M-1; j>=0; --j)
                printf("%d",a[b[j]]);
            printf("\n");
        }
    }
}
// m为你要从a中的len个数当中选出的数的个数。
void Combine(int *a,int len,int m)
{
        if(NULL == a || len<1 || m < 1 || m > len)
        return ;  
    int *tmp = (int *)malloc(m*sizeof(int));
    Combine2(a,len,m,tmp,m);
    free(tmp);
}
  1. 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
  2. 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
  3. 当第一个“1”移动到数组的n-m的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。
    例如求5中选3的组合:
    1 1 1 0 0 //1,2,3
    1 1 0 1 0 //1,2,4
    1 0 1 1 0 //1,3,4
    0 1 1 1 0 //2,3,4
    1 1 0 0 1 //1,2,5
    1 0 1 0 1 //1,3,5
    0 1 1 0 1 //2,3,5
    1 0 0 1 1 //1,4,5
    0 1 0 1 1 //2,4,5
    0 0 1 1 1 //3,4,5

上一篇下一篇

猜你喜欢

热点阅读