其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
字典序法的优点是排列的结果按照顺序输出并且对于重复的元素不进行重复排序
我们先看一个例子。
示例: 1 2 3的全排列如下:总数应该为3!.
1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1
我们这里是通过字典序法找出来的。
那么什么是字典序法呢?
从上面的全排列也可以看出来了,从左往右依次增大,对这就是字典序法。可是如何用算法来实现字典序法全排列呢?
我们再来看一段文字描述:(用字典序法找124653的下一个排列)
你主要看红色字体部分就行了,这就是步骤。
如果当前排列是124653,找它的下一个排列的方法是,从这个序列中从右至左找第一个左邻小于右邻的数,
如果找不到,则所有排列求解完成,如果找得到则说明排列未完成。
本例中将找到46,计4所在的位置为i,找到后不能直接将46位置互换,而又要从右到左到第一个比4大的数,
本例找到的数是5,其位置计为j,将i与j所在元素交换125643,
然后将i+1至最后一个元素从小到大排序得到125346,这就是124653的下一个排列。
下图是用字典序法找1 2 3的全排列(全过程):
public void PermutationWithDictionary(char chs[])
{
Arrays.sort(chs);
//先对数组的元素进行依次排序
while(true)
{
System.out.println(chs);
int j=chs.length-1;
int index=0;
for(j=chs.length-2;j>=0;j--)
{
if(chs[j]<chs[j+1])
{
index=j;
break;
//从右向左找到第一个非递增的元素
}
else if(j==0){
return;
}
}
for(j=chs.length-1;j>=0;j--)
{
if(chs[j]>chs[index])
break;
//从右向左找到第一个比非递增元素大的元素
}
Swap(chs,index,j);
//交换找到的两个元素
Reverse(chs,index+1);
//对非递增元素位置后面的数组进行逆序排列
}
}
public static void Reverse(char chs[],int i)
{
int k=i,j=chs.length-1;
while(k<j)
{
Swap(chs,k,j);
k++;
j--;
}
}
public static void Swap(char chs[],int i,int j)
{
char temp;
temp=chs[i];
chs[i]=chs[j];
chs[j]=temp;
}