组合函数递归和非递归实现

             最近笔试了一个关于组合算法的非递归算法,以前写过递归的算法,http://blog.csdn.net/dremi/archive/2007/12/15/1940723.aspx

但这次要用非递归去实现,在有限的时间里,确实没有想的太周到,只是大概的思想写了一下,可能也有点紧张了。现在再来把它完整的来实现, 包括算法思想:代码

#include  " stdafx.h "
#include 
< iostream >

void  print( int  a[],  int  n,  int  b[])
{
    
for(int i = 0; i < n; i++)
        std::cout
<<b[i]<<" ";
    std::cout
<<" -------> ";
    
for(int i = 0; i < n; i++)
        
if(b[i])
            std::cout
<<a[i]<<"  ";
    std::cout
<<" ";
}


//
// 非递归实现从a数组(n个)中选取m个的组合排列
//  int b[]: 中的b[i] = 1是表示a[i]选上,否则表示没有选上
// 算法的思想:
// 利用n个0,1来表示一种组合排列。像n = 5, m = 3,则 
// 排列可以为:
/*
                111<-00
                1101<-0
                11<-001
                1011<-0
                101<-01
                1<-0011
                0111<-0
                011<-01
                01<-011
                00111
其中"<-"表示箭头右边的0和左边的1交换,还要把从这个交换位置(即0的位置)起右边所有的1都放在一起,
并且紧跟在此位置后面,然后在是其它的0,如下面变换:
11001--->10110
首先找到那个交换点:
        11001---->10101------->10 110
          ^                                   ^^
        交换点   交换后    把交换点后面的1都紧放在它的后面去 
*/

//
void  combine( int  a[],  int  n,  int  m,  int  b[] )
{
    
int cnt = 0//记录交换点1的个数
    int index ;  //记录交换点的位置
    int i;
    
//初始化b[] = {0}
    memset(b, 0sizeof(int)*n);
    
//让前m个b[]为1
    for(i = 0; i < m; i++) b[i] = 1;
    print(a, n, b);
    
do 
    
{
        
        cnt 
= 0;
        
for(index = n - 1; index > 0; index--)
        
{
            
if(b[index] == 0 && b[index-1== 1// 扫描到"10"
                break;
            
if(1 == b[index] ) cnt++//统计1的个数
        }

        
if(index > 0)
        
{
            
int t = b[index];
            b[index] 
= b[index - 1];
            b[index 
- 1= t;
            
//右边cnt个"1"紧跟其后
            for( i = 1; i <=  cnt; i++)
                b[i 
+ index] = 1;
            
for(i = i + index; i < n; i++) b[i] = 0;//再把cnt个"1"后面加上"0"
            print(a, n, b);
        }

        
//当从右向左扫描,index <= 0表示0已经都转到左边去了,应该退出
    }
while(index > 0);
}



int  _tmain( int  argc, _TCHAR *  argv[])
{
    
int a[] = {123456};
    
int b[10];
    combine(a, 
63, b);
    
    system(
"pause");
    
return 0;
}

 

   测试结果如下:

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值