C语言实现数学上的组合和排列

今天想用C语言实现下数学上的组合和排列,一直很郁闷。

上网搜索到一个例子:

 

#include <stdio.h>

#include <stdlib.h>

//n个元素的数组a中,取m个元素的组合

bool zuhe(char a[],int n,int m)

{//p[x]=y 取到的第x个元素,是a中的第y个元素

    int index,i,*p;

   

    p=(int*)malloc(sizeof(int)*m);

    if(p==NULL)

    {

        return false;

    }

    index=0;

    p[index]=0;//取第一个元素

    while(true)

    {

        if(p[index]>=n)

        {//取到底了,回退

            if(index==0)

            {//各种情况取完了,不能再回退了

                break;

            }

            index--;//回退到前一个

            p[index]++;//替换元素

        }

        else if(index==m-1)

        {//取够了,输出

            for(i=0;i<m;i++)

            {

                printf("%c",a[p[i]]);

            }

            printf("\n");

            p[index]++; //替换元素

        }

        else

        {//多取一个元素

            index++;

            p[index]=p[index-1]+1;

        }

       

    }

    free(p);

    return true;

}

//n个元素的数组a,进行全排列

bool pailie(char a[],int n)

{//p[x]=y 取到的第x个元素,是a中的第y个元素

    int i,j,temp,*p;

   

    p=(int*)malloc(sizeof(int)*n);

    if(p==NULL)

    {

        return false;

    }

    for(i=0;i<n;i++)

    {//初始排列

        p[i]=i;

    }

    while(true)

    {//循环m=n!

        //输出一种排列情况

        for(i=0;i<n;i++)

        {

            printf("%c",a[p[i]]);

        }

        printf("\n");    

        //从后向前查找,看有没有后面的数大于前面的数的情况,若有则停在后一个数的位置。

        for(i=n-1;i>0 && p[i]<p[i-1];i--);   

       

        //若没有后面的数大于前面的数的情况,说明已经到了最后一个排列,返回

        if(i==0) break;

       

        //从后查到i,查找大于p[i - 1]的最小的数,记入j

        for(j=n-1;j>i && p[j]<p[i-1];j--);

       

        //交换p[i-1]p[j]

        temp=p[i-1];p[i-1]=p[j];p[j]=temp;

       

        //倒置p[i]p[n-1]

        for(i=i,j=n-1;i<j;i++,j--)

        {//交换p[c]p[d]

            temp=p[i];p[i]=p[j];p[j]=temp;

        }

    }

    free(p);

    return true;

}

int main()

{

    char a[]="ABCD";

   

    zuhe(a,4,2);//组合

    pailie(a,3);//排列

    return 0;

}

 

上述算法用于一个题目

其实今天做了一道题目,是一个全国C语言比赛的编程题目

完整程序如下:

硬件平台:i3 intel

软件平台:eclipse cdt

 

 

 

struct GoodChoiceSteel

{

       int order;

       int lenth;

       int group;

};

int combination(int *a, int n, int m, int totalmark, struct GoodChoiceSteel *result, int *rCountP);

int Choose_Best_Steel(int s, int n, const int *p, struct GoodChoiceSteel *result, int *rCountP);

 

int combination(int *a, int n, int m, int totalmark, struct GoodChoiceSteel *result, int *rCountP)

{//p[x]=y 取到的第x个元素,是a中的第y个元素

    int index,i,*p;

    int totalTmp = 0;

  //  static int rCount = 0;

    result[0].group = 1;

   // p=(int*)malloc(sizeof(int)*m);

   // memset(p, 0, sizeof(int)*m);

    p = (int *) calloc(m, sizeof(int));

    if(p==NULL)

    {

        return EXIT_FAILURE;

    }

    index=0;

    p[index]=0;//取第一个元素

    while(1)

    {

        if(p[index]>=n)

        {//取到底了,回退

            if(index==0)

            {//各种情况取完了,不能再回退了

                break;

            }

            index--;//回退到前一个

            p[index]++;//替换元素

        }

        else if(index==m-1)

        {//取够了,输出

            for(i=0;i<m;i++)

            {

                printf("%d",a[p[i]]);

                result[*rCountP].order = p[i];

                result[*rCountP].lenth = a[p[i]];

                (*rCountP)++;

                //rCount++;

                totalTmp += a[p[i]];

            }

            if(totalTmp != totalmark)

            {

                   *rCountP =  *rCountP - m;

            }

            if(totalTmp == totalmark)

            {

                    //rCount =  rCount - m;

                   result[*rCountP].group = 1;

            }

            totalTmp = 0;

            printf("\n");

            p[index]++; //替换元素

        }

        else

        {//多取一个元素

            index++;

            p[index]=p[index-1]+1;

        }

    }

    /

        if (n > 1){

           

               combination_recursion(i - 1, n - 1);

        }else{

           

            for (j = comb[0]; j > 0; j--){

                printf("%c", comb[j] + 64);

            }

            printf(" ");

        }

    }

}

 

 

 

 

int main(void)

{

       //puts("!!!play in C!!!");

 

       Choose_Best_Steel_Demo();

       //comb[0] = 2;

 

       //    combination(4, 3);       

       //char a[]="ABCD";

       //int a[] = {1, 2, 3, 4};

 

 

 

 

       return EXIT_SUCCESS;

}

 

 

 

 

转载于:https://www.cnblogs.com/nickchan/archive/2011/08/19/3104540.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值