配列組合せC++実装
4412 ワード
最近一つの試験を準備して、組み合わせを試験する内容があることを発見したので、この問題を研究します.まず配列の問題を検討する.
例えば1,2,3,4の配列を求める
1つ目の方法:
この方法は効率が悪いので,輪替え法を用いた第2の方法が生まれた.
2つ目の方法:
しかし1,2,…,Nを求めるときには第2の方法が求めにくいので,第2の方法(再帰)を書き換える.
3つ目の方法:
組合せ問題の比較的簡単な実現関数は以下の通りである.
例えば1,2,3,4の配列を求める
Int a[]={1,2,3,4}
1つ目の方法:
void ArrangementS(int *a)
{
int count=0;
for(int i=0;i<4;++i)
for(int j=0;j<4;++j)
for(int k=0;k<4;++k)
for (int s=0;s<4;++s)
if(i!=j && i!=k && i!=s && j!=k && j!=s && k!=s)
{
cout<<a[i]<<" "<<a[j]<<" "<<a[k]<<" "<<a[s]<<" "<<endl;
count++;
}
cout<<count<<endl;
}
この方法は効率が悪いので,輪替え法を用いた第2の方法が生まれた.
2つ目の方法:
void method2(int *a)
{
int count=0;
for(int k=0;k<4;k++)
{
if(k!=0)
{
swap(a[0],a[k]);
}
for(int j=1;j<4;j++)
{
if(j!=1)
{
swap(a[1],a[j]);
}
for(int s=2;s<4;s++)
{
if(s!=2)
{
swap(a[2],a[s]);
}
std::cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<endl;
count++;
if(s!=2)
{
swap(a[2],a[s]);
}
}
if(j!=1)
{
swap(a[1],a[j]);
}
}
if(k!=0)
{
swap(a[0],a[k]);
}
}
std::cout<<count<<endl;
}
しかし1,2,…,Nを求めるときには第2の方法が求めにくいので,第2の方法(再帰)を書き換える.
3つ目の方法:
void arrangement(int *a,int start,int end)
{
if(start==end)
{
for(int i=0;i<N;++i)
std::cout<<a[i]<<" ";
std::cout<<endl;
return;
}
for(int i=start;i<=end;++i)
{
if(i!=start)
swap(a[start],a[i]);
arrangement(a,start+1,end);
if(i!=start)
swap(a[start],a[i]);
}
}
組合せ問題の比較的簡単な実現関数は以下の通りである.
void Portfolio(int *a,int start,int end,int nselN)
{
static int nselTemp=nselN;
static std::vector<int> selArray(nselN);
if(nselN==0)
{
for(int i=0;i<nselTemp;++i)
cout<<a[selArray[nselTemp-i-1]]<<" ";
cout<<endl;
return;
}
for(int i=start;i<=end-nselN+1;++i)
{
selArray[nselN-1]=i;
Portfolio(a,i+1,end,nselN-1);
}
}