zoukankan      html  css  js  c++  java
  • 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;

    }

     

     

     

  • 相关阅读:
    Java工程代码开发规范总结
    MySQL5.7 JSON字段性能测试
    Forest v1.5.12 发布,声明式 HTTP 框架,已超过 1.6k star
    HTTP基础系列之:一文搞懂URL
    近1000 star,Forest 1.5.0 正式版发布
    我的开源项目在五个月内超过了 600 star
    我的开源经历:为了方便处理三方 HTTP 接口而写的 Java 框架
    【约瑟夫环】C语言数组法+java循环链表法
    UNICODE编码 特殊符号
    swift3.0 保存图片到本地,申请权限
  • 原文地址:https://www.cnblogs.com/nickchan/p/3104540.html
Copyright © 2011-2022 走看看