字典序法求一个数组的全排列4

来源:互联网 发布:源码本地放到php打不开 编辑:程序博客网 时间:2024/04/30 01:57

全排列算法,大致来讲有四种字典序法,递增进位制数法,递减进位制数法,邻位对换法,这里讲一下字典序方法。

首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9)。以字典序为基础,我们可以得出任意两个数字串的大小。

比如字符串“abcdg”和“abcfdg”,我们从左到右比较每一个字符的大小,发现第四个字符‘d’和‘f’,‘f’的字典序更大,因此前一个字符串比后一个字符串的字典序要小。

因此,对与“abc”,他的字典序最大的值是“cba”,最小的值是“abc”,其他的排序的字典序都在他们之间。因此,求一个串的全排列,我们只需要从串的字典序最小的排列开始,求出当前字典序的下一个字典序排序,直到字典序的值最大。我们就求出了所有的全排列!!!

对于,“abc”,我们从最小字典序“abc”开始,依次有:

abc(最小)     acb   bac   bca    cab     cba(最大)

那么对于当前的序列我们如何求,他的下一个字典序呢.(所谓一个的下一个就是这一个与下一个之间没有其他的)

一般算法可以分为三步:

对于串 5,8,7,9,3,6,4,2,1

1.我们从右向左找到第一个a[i],满足a【i】<a【i+1】,这里a【i】=3;

2.我们从a【i】开始向后,找最后一个a【j】>=a【i】,这里a【j】=4;

3.交换a【i】,和a【j】,有串 5,8,7,9,4,6,3,2,1

反转i位置后所有的元素5,8,7,9,41,2,3,6,得到下一个全排列

//arr是要排列的数组,n是数组的长度,当不存在下一个排列时返回false;bool NextPermutation(int * arr,int n){int i,j,k;for(i=n-1;i>0;i--)//从尾巴开始找第一个arr【i】>arr【i-1】if(arr[i]>arr[i-1]) break;if(i==0) //如果没找到,则输入的已经是最大字典序return false;i--;for(j=i+1;j<n;j++)//从i之后,开始找第一个不大于,a【i】的数,if(arr[i]>=arr[j])//注意这里是不大于!!!break;j--;swap(arr[i],arr[j]);j=n-1;i=i+1;while(i<j)swap(arr[i++],arr[j--]);return true;}

字典序的不但能解决排列问题,也能解决组合问题,比如:从5个球中取三个,我们只要对0,0,0,1,1这样一个数组按照字典序进行全排列,就能遍历出所有组合。!!!!!当然,我们可以用stl里的next_permutation函数实现全排列!!!


0 0
原创粉丝点击