再帰復習、再帰出力文字列の全配列


/*
  123     ,         
1)1       ,    2,3     ;
2)2       ( 2 1  ),    1,3     ;
3)3       ( 3 1  ),    1,2     ;
    ,                ,             (       1    )
                        ,          ;
                   ,              。
 */
#include
using namespace std;

template 
void Perm(Type list[], int k, int m) //list[k...m]
//k m               ,      index,k    index,m     index。 
{
	if(k==m)                       
	{
		for(int i=0; i<=m; i++)
			cout << list[i];
		cout << endl;
	}
	else
		for(int j=k; j<=m; j++)
		{
			Swap(list[k],list[j]);
			Perm(list, k+1, m);
			Swap(list[k],list[j]);
		}
}

template
inline void Swap(Type &a, Type &b)
{
	Type temp=a;
	a=b;
	b=temp;
}

int main(){
	char ch[]="abc";
	Perm(ch,0,3);

}

原理は
perm(abc)=a+perm(bc)---aとaを交換し、サブ問題を計算し、還元を計算した.
+b+perm(ac)---aとbを交換し、同上
+c+perm(ba)---aとcを交換し、同上
サブ問題はこのように推定される.
3つを組み合わせてforループで処理します.
for(int j=k; j<=m; j++)
		{
			Swap(list[k],list[j]);//          [j]   。
			Perm(list, k+1, m);//                      。
			Swap(list[k],list[j]);//           [j]    。
		}
forループは、複数の再帰を累積する.