求解组合序列

今天用到了求解组合序列的算法,并用C++和OCaml做了实现。

问题描述:有数组(链表等)a,长度len,从里面取出n个元素,给出所有的取出序列。

 

这是排列组合问题,共有C(len,n)个序列,高中学过的。实现的流程其实比较简单,如下:

设当前位置s,则可以先取a[s],然后从余下的元素中取出n-1个元素,一起组成一个序列;

或不取a[s],从余下的元素中取出n个元素作为一个序列

迭代该过程

C++代码

#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> > pick(int l[],int s,int e,int n)
{
	vector<vector<int> > v;
	if(e-s+1>=n&&n>0)
	{
		vector<vector<int> > res1 = pick(l,s+1,e,n-1);
		int size=res1.size();
		if(size>0)
		{		
			for(int i=0;i<size;i++)
			{
				res1[i].push_back(l[s]);
			}
		}else
		{
			vector<int> tmp;
			tmp.push_back(l[s]);
			res1.push_back(tmp);
		}
		vector<vector<int> > res2 = pick(l,s+1,e,n);
		size=res2.size();
		for(int i=0;i<size;i++)
		{
			res1.push_back(res2[i]);
		}
		v= res1;
	}
	return v;
}
int main()
{
	int coe[]={1,2,3,4,5};
	
	vector<vector<int> > res = pick(coe,0,4,3);
	int size=res.size();
	for (int i=0;i<size;i++)
	{
		vector<int> v=res[i];
		int len=v.size();
		for (int j=0;j<len;j++)
		{
			cout<<v[j]<<",";
		}
		cout<<endl;
	}
}

运行结果

OCaml代码

 1 let rec pick a s e len =
2 let v = ref [] in
3 if e-s+1>=len&&len>0 then
4 begin
5 let len0 = len in
6 let res1 = pick a (s+1) e (len-1) in
7 let len = List.length !res1 in
8 let ele = List.nth a s in
9 if len>0 then
10 begin
11 List.iter(fun r->
12 r := ele::!r;
13 )!res1;
14 end else
15 begin
16 res1 := [ref [ele]];
17 end;
18
19 let res2 = pick a (s+1) e len0 in
20 List.iter(fun r->
21 res1 := r::!res1;
22 )!res2;
23
24 v := !res1;
25 end;
26
27 v
28 in
29
30 let a = [1;2;3;4;5] in
31 let res = pick a 0 4 3 in
32
33 List.iter(fun r->
34 List.iter(fun r1->
35 Printf.printf "%d," r1;
36 )!r;
37 Printf.printf "\n";
38 )!res;

运行结果




posted on 2012-03-26 23:07  小交响曲  阅读(264)  评论(0编辑  收藏  举报

导航