java实现全排列_Java实现全排列

①假设全排列函数为f(n)=n!,那么可以立刻知道f(n+1)=(n+1)Xn!=(n+1)*f(n),因此可以利用递归方便地实现。在递归前所要做的事情就是把该步递归中的第一个元素与后面几个元素进行交换,并在递归结束后交换回来。同时,当递归的第一个元素移动到数组末尾时,表示完成一次排列,此时可将整个数组进行输出。代码如下:

public class exam {

static int count;

public static void main(String[] args)throws Exception {

// TODO Auto-generated method stub

count=0;

String str="aabb";

char[] cs=str.toCharArray();

perm(cs,0);

System.out.print(count);

System.exit(0);

}

//全排列的递归算法

private static void perm(char[] c,int index)throws Exception{

//打印当前序列

if(index>=c.length){

for(int i=0;i

System.out.print(c[i]+" ");

System.out.print("\n");

count++;

}

//进行交换和递归

for(int i=index;i

if(!check(c,index,i)){ //对于重复元素,先与第一次出现的字符交换并求全排列,后面再出现的就不进行交换和求全排列的过程

swap(c,index,i);

perm(c,index+1);

swap(c,index,i);

}

}

}

//数组里两个值交换

private static void swap(char[] c,int index1,int index2)throws Exception{

char t=c[index1];

c[index1]=c[index2];

c[index2]=t;

}

//去重函数

private static boolean check(char[] c,int index1,int index2){

while(index1

if(c[index1]==c[index2])

return true;

index1++;

}

return false;

}

}

其中去重函数并不是必要的。

②第二种方式不通过递归而是迭代实现。迭代方法借助了字典序。字典序顾名思义就是在编排字典时采用的排序方式。比如单词monster和monitor,它们前三个字母相同,第四个字母s比i大,因此monster会排在monitor的后面。

使用字典序的关键是找到当前序列所紧挨着的下一个序列。假设有序列a,一般思路是从a的末尾开始比较a[index-1]和a[index],若a[index-1]

因此,可先将原序列从小到大排序,获取最小序列,然后一直迭代直到找不到下一个序列为止。代码如下。

public class PermInteration {

public static void main(String[] args) {

int count=0;

String str="hbbb";

char[] c=str.toCharArray();

sort(c,0); //先排序

print(c);

count++;

while(getNextPerm(c)){

count++;

}

System.out.println(count);

System.exit(0);

}

//获取下一个字典序列

private static boolean getNextPerm(char[] c){

int end=c.length-1;

int flag=0;

int min=0;

int index=end;

while(index>0&&c[index]<=c[index-1]){

index--;

}

if(index==0)

return false;

flag=index-1;

min=index;

for(int i=index;i<=end;i++){

if(c[i]>c[flag]&&c[i]

min=i;

}

swap(c,flag,min);

sort(c,index);

print(c);

return true;

}

//交换

private static void swap(char[] c,int index1,int index2){

char t=c[index1];

c[index1]=c[index2];

c[index2]=t;

}

//对index及后面的元素排序

private static void sort(char[]c,int index){

int min;

for(int i=index;i

min=i;

for(int j=i;j

if(c[j]

min=j;

}

swap(c,i,min);

}

}

//打印数组

private static void print(char[] c){

for(int i=0;i

if(i==c.length-1)

System.out.print(c[i]+"\n");

else

System.out.print(c[i]+" ");

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值