蔡諝的窝

博客园 首页 新随笔 联系 订阅 管理

全排列问题基本都可以转化成对1~n的数字的全排列,所以本文只讨论1~n的全排列问题。

题目:1~n的全排列

思想: 

  1. 用数组记录操作后的序列,输出结果时只需要输出该数组即可;
  2. 交换第1个元素与第i(1=<i<=n)个元素,得到n个序列;把每个序列分成两部分:第一个元素,其余的元素;对其余元素执行全排列操作;(记得操作完后,将这两个元素交换回来,以方便下面的交换)
  3. 当剩余序列中只有一个元素时,得到一种排列结果,输出该结果

猜想结果:

1~4的全排列的个数:24,输出结果依此为:

1234    1243    1324    1342    1432    1423    2134    2143    2314    2341
2431    2413    3214    3241    3124    3142    3412    3421    4231    4213
4321    4312    4132    4123

三思:

  • 该算法怎么不是按顺序排列?因为算法本身特点,只是在大框架下保证顺序输出【记以1开头的6个,接着是以2开头的,接着以3开头的序列(首个为3214),……】;由于1234因调换<1-3>就出现了3214且以其作为3序列的开头,而3124比它小,却只能排在它后面。
  • 给算做的调换都是有效调换,时间主要耗在函数调用上。(其实更耗时间的该是打印结果)
  • 如果数组有重复怎么办?,例:求“1223”的全部排列?

代码:

 1 #include <iostream>
2 using namespace std;
3 const int MaxNum=9;
4 int iArr[MaxNum];//定义数组
5 int count;//定义计数器
6 inline void Swap(int *a,int *b)//交换两个位置的值
7 {
8 int temp;
9 temp=*a;
10 *a=*b;
11 *b=temp;
12 }
13 int FullArray(int k,int m)//对下标为k~m的数进行全排列
14 {
15 int i=0;
16 if(k==m){
17 for(i=0;i<=m;i++){//用输出数组值的方法,使问题得到简化;回避了好些问题,如果把值一个个输出问题就复杂了
18 cout<<iArr[i];//由于设置MaxNum=9;当MaxNum设置超过9时记得改为cout<<iArr[i]<<" ";
19 }
20 cout<<endl;
21 count++;
22 return 1;
23 }
24 for(i=k;i<=m;i++){//第一次是无效替换——Swap(&iArr[k],&iArr[k]);这是个技巧
25 Swap(&iArr[k],&iArr[i]);
26 FullArray(k+1,m);
27 Swap(&iArr[i],&iArr[k]);
28 }
29 return 1;
30
31 }
32 void main()
33 { //此程序只对1~n进行全排列;
34   //如果需要对给定int数组进行全排列,则需修改iArr[MaxNum]的赋值;
35   //如果需要对给定char数组进行全排列,则可以把iArr[MaxNum]的值当下标使用;
36 int n,i;
37 for(i=0;i<MaxNum;i++)iArr[i]=i+1;//初始化数组,其存储的值依次为1,2,3,……
38 while(1){
39 system("cls");
40 count=0;//测试新用例时,count重新置0
41 cout<<"请输入n(最大为9):";
42 cin>>n;
43 if(n>MaxNum || n<1){cout<<"Error: n的值在设定值范围之外"<<endl;break;}
44 FullArray(0,n-1);
45 cout<<"1~"<<n<<"的全排列的个数:"<<count<<endl;
46 system("pause");
47 }
48 }

参考:http://plutoblog.iteye.com/blog/976216

posted on 2011-10-31 10:24  蔡諝  阅读(15526)  评论(0编辑  收藏  举报