求解组合序列
今天用到了求解组合序列的算法,并用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;
运行结果

浙公网安备 33010602011771号