求集合的组合和排列问题

      排列组合为数学中常见问题,但是正要用算法表示出来相信还是有一定困难的.这里将用递归算法实现排列和组合问题 

   1)组合问题

  

算法实现如下:

//求组合
//i表示当前处理是那个元素,src表示要求组合的原集合,n表示原集合中元素的个数
//a用于存储元集合的一个组合,m表示a重元素的个数
void Combination(int i,int * src,int n,int * a,int m)
{
   if(i>=n)
     printSet(a,m);
   else
   {
	   a[m]=src[i];
       Combination(i+1,src,n,a,m+1);
       Combination(i+1,src,n,a,m);
   }
}

其中printSet函数打印出集合a中前m个元素,这里实际上是打印出满足条件的一个子集

//输出集合a中前m个数显示
void printSet(int * a,int m)
{
	for(int i=0;i<m;i++)
		cout<<a[i];
	cout<<endl;
}
2)排列问题

 

从分析中可以看出这是典型的递归思路,排列算法如下:

//求排列
void Permutation(int * src,int n,int * a,int i)
{
	if(i<0)
	{
	    printSet(a,n);
	}
	else
	{
        for(int j=i;j>=0;j--)
		{
           int temp=src[i];
		   src[i]=src[j];
		   src[j]=temp;
		   a[i]=src[i];
           Permutation(src,n,a,i-1);
           temp=src[i];
		   src[i]=src[j];
		   src[j]=temp;
		}
	}
}

下面是求集合src={1,2,3}的排列组合的完整代码

#include "stdafx.h"
#include <iostream>
using namespace std;

//输出集合a中前m个数显示
void printSet(int * a,int m)
{
	for(int i=0;i<m;i++)
		cout<<a[i];
	cout<<endl;
}

//求组合
//i表示当前处理是那个元素,src表示要求组合的原集合,n表示原集合中元素的个数
//a用于存储元集合的一个组合,m表示a重元素的个数
void Combination(int i,int * src,int n,int * a,int m)
{
   if(i>=n)
     printSet(a,m);
   else
   {
	   a[m]=src[i];
       Combination(i+1,src,n,a,m+1);
       Combination(i+1,src,n,a,m);
   }
}

//求排列
void Permutation(int * src,int n,int * a,int i)
{
	if(i<0)
	{
	    printSet(a,n);
	}
	else
	{
        for(int j=i;j>=0;j--)
		{
           int temp=src[i];
		   src[i]=src[j];
		   src[j]=temp;
		   a[i]=src[i];
           Permutation(src,n,a,i-1);
           temp=src[i];
		   src[i]=src[j];
		   src[j]=temp;
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int src[]={1,2,3};
	int n=sizeof(src)/sizeof(int);
	int * a=new int[n]; 
	cout<<"1,2,3的组合结果如下:"<<endl;
    Combination(0,src,n,a,0);
	cout<<"1,2,3的排列结果如下:"<<endl;
    Permutation(src,n,a,n-1);
	delete [] a;
	system("PAUSE");
	return 0;
}

运行结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值