数列的排列与组合问题

关于数列的全排列已经另外一篇文章中提到过了,

 

下面来介绍下数列的组合问题:

 

例如;序列12345  如果输入m=3,原序列的长度n=5

得到的组合数组是:123 124 125 134 135 145 234 235 245 345

如上得到所有的位数为2的组合方式,从上面的数我们也可以用序号表示:

a[0],a[1],a[2],a[3],a[4],a[5]

 

得到的组合数a[0],a[1],a[2]可用下标012表示

 

那么组合数就可以用原来数列的的下标表示即可:

 

从一开始,得到的组合数列,所有组合数的下标是递增 的,最后一个组合序列的最后一位的下标即为n-1;

 

我们定义一个数组p[x]=y  取到的第x个元素是数组a中的第y个元素 x代表的是组合序列的中的元素的索引  y代表的是数组a中的元素索引。

 

#include<stdio.h>
#include <stdlib.h>

bool zuhe(char a[],int n,int m)
{
   int index,i,*p;
   p=(int*)malloc(sizeof(int)*m);
    if(p==NULL)
    {
        return false;
    }
    index=0;//index代表的是组合串中的元素的索引,即代表组合数中的第几个数
    p[index]=0;//取第一个元素,从一个元素开始
    

    while(true)
   {
          /*组合数中的某一个位置的元素到达原数组最后一个                              原素了,比如15_  或者125  其中的5 达到数组的最后一个元素*/
         if(p[index]>=n)
        {
              if(index==0)
              {
                  //此时组合的第一个数也达到了数组中的最后一个数。退出循环
                  break;
               }
               index--;     //此时的组合数列的index位置上的数已经达到数组最后一个数,所以回到前一个位置,将其加1 ps. 135--->14_
               p[index]++; 
        }
        else if(index==m-1)//此时已经组合到最后一个位置,可以输出
        {
             for(i=0;i<m;i++)
            {
                printf("%c",a[p[i]]);
            }
            printf("\n");
            //此时的index已经达到组合数的最后一个位置,exp 134->135
            p[index]++;
        }
        else //此时index还未达到最后的位置exp 13_--->134
        {
              index++;
              p[index]=p[index-1]+1;
          }
    }
}

 但是上述办法还是不能解决原数列出现重复元素的问题:还得需要后期的去重处理。

 

 

如果将这些求一个数列的排列组合的方法结合起来,就可以解决如下的一个问题

 

 

 

问题:

当给以出一个数列,求出其所有的组合函数,比如abc  输出:a,b,c,ad,ac,bc,abc

 

只需在上面的基础之上加一个for循环即可:

 

main()
{
	char a[]="12345";
	for(int i=1;i<=5;i++)
	{
		printf("i:%d:\n",i);
		zuhe(a,5,i);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值