排列组合为数学中常见问题,但是正要用算法表示出来相信还是有一定困难的.这里将用递归算法实现排列和组合问题
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;
}
运行结果如下: