打印全排列

摘要:
Intk){if(k==a.length-1){System.out.println(Arrays.toString(a));}else{for(int i=k;voidprintRange(chara[]){for(int i=0;i++){num[i]=i;moveNext(num);当num变为210时,hasNext(num;

打印出一个字符串的全排列,有很多方法,最容易看到的是递归的方法。

void range(char a[], int k){

if(k==a.length-1){

System.out.println(Arrays.toString(a));

}

else {

for(int i=k;i<a.length;i++){

swap(a[i],a[k]);

range(a,k+1);

swap(a[k],a[i]);

}

}

还可以借助栈来把上面的改成非递归。

当然还有其他的方法,比如

1、字典序方法。

写的时候借助一个Num[]辅助数组。

void printRange(char a[]){

for(int i=0;i<a.length;i++){

num[i]=i;

}

while(hasNext(num)){

print(a,num);

moveNext(num);

}

------

比如abc对应辅助数组初始状态是012,当num变成210是hasNext(num)为false;

当怎样从012生成下一个呢?

比如124653,我们要找到它的下一个数字串,使用的方法是

1、从右到左扫描,找到一个位置,num[pos]<num[pos+1],然后从pos+1向后扫描,在所有大于num[pos]的数字当中找到一个最小的,记录位置k,

然后交换num[pos]和num[k]

 2 之后,将pos+1~n-1位置的字符互换, 即reverse the substring from pos+1 to n-1.

另外一种方法叫做进制递增法。

http://llfclz.itpub.net/post/1160/278490

设想有 n 个数字先取第一个数字再取第二个数字第二个数可以放在第一个数的左或右面就是有 0, 1 两个选择再取第三个数放到前面选好的两个数字中可以放在最左中间最右就是有 0, 1, 2 三个选择很自然吗忽然你想到了二进位八进位那些数系转换关系。可以设计这样一个数, ...xyz, 其中个位数 z 是二进位的也就是放第二个数的两个位置十位数 y 是三进位的代表放第三个数字的三个位子然后百位数是四进位千位数是五进位的依以类推." 没错这样设计的话如果 0 表示放於最左面的话 "2021" 这个数就代表了排列五个元素 (abcde), 取一个 a, 然后第二个 b 放在 a 的右面成 ab,  c 放到最右面成为 abc,  d 放到最左面成 dabc; 最后 e 放到中间去成为 daebc. 至於 "2021" 这个特别的设计的数可以用2*5+ 0*4 + 2*3 + 1*2 这样的计算来映对到自然数的数列上去。

如求 4 个数的 4! = 24 个排列 18 个排列可以这样求得, 18  2, 余数是 0, 所以第二个数放在第一个数的左面然后商 9 再除 3, 余数 0,所以第三个数於在头两个数的最左最后 3 除以 4, 余数是 3, 因此第四个数要放在前三个数的第 4 个空位也就是最右面。

 

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 /* A!全排列
 5  * Algorithm Description
 6  * 进制递增
 7  * 
 8  */
 9 public class Al2 {
10     private int factorial(int n){
11         int sum=1;
12         for(int i=1;i<=n;i++){
13             sum*=i;
14         }
15         return sum;
16     }
17     private void insert(int pos, char ch, char []cArr){
18         if(cArr[pos]!=' '){
19             for(int i=cArr.length-1;i>pos;i--){
20                 cArr[i]=cArr[i-1];
21             }
22             cArr[pos]=ch;
23         } else{
24             cArr[pos]=ch;
25         }
26     }
27     private void solve(String str){
28         int n=str.length();
29         int m=factorial(n);
30         int []num=new int[n-1];
31         char []cArr=new char[n];
32         int i,j;
33         for(i=0;i<m;i++){
34             Arrays.fill(cArr, ' ');
35             cArr[0]=str.charAt(0);
36             int c=i;
37             for(j=2;j<=n;j++){
38                 num[j-2]=c%j;
39                 c=c/j;
40             }
41             //System.out.print(Arrays.toString(num)+" ");
42             for(j=0;j<n-1;j++){
43                 insert(num[j],str.charAt(j+1),cArr);
44             }
45             //System.out.println("i="+(i+1)+": "+Arrays.toString(cArr));
46         }
47     }
48     public static void main(String args[]){
49         Scanner sc=new Scanner(System.in);
50         long startTime=System.currentTimeMillis();
51         new Al2().solve(sc.nextLine());
52         long endTime=System.currentTimeMillis();
53         System.out.println("Time cost: "+(endTime-startTime));
54     }
55 }

 

 

免责声明:文章转载自《打印全排列》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇BZOJ4402 Claris的剑, 【2020六校联考NOIP #1】山水画MongoDB 删除文档下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring的学习(四、Spring事务管理)

Spring事务管理的三个核心接口 Spring的事务管理是基于AOP实现的,而AOP是以方法为单位的。 Spring的事务属性分别为传播行为、隔离级别、只读和超时属性。所有这些属性提供了事务应用的方法和描述策略。 事务管理的三个核心接口:PlatformTransactionManager、TransactionDefinition、Transactio...

ASCII 非打印字符

项目出了问题,因为AscII非打印字符的原因,后来找了一下啊ASCII的非打印字符,总共有31个,然后我们直接全部替换成问号了. 解决方式为先找到非打印字符,这是我从网上找的非打印字符表: 进制 十六进制 字符   十进制 十六进制 字符 0 00 空   16 10 数据链路转意 1 01 头标开始   17 11 设备控制 1 2 02...

.net 多线程的使用(Thread)

 上篇 net 同步异步   中篇 多线程的使用(Thread)   下篇 net 任务工厂实现异步多线程 Thread多线程概述  上一篇我们介绍了net 的同步与异步,我们异步演示的时候使用的是委托多线程来实现的。今天我们来细细的剖析下 多线程。 多线程的优点:可以同时完成多个任务;可以使程序的响应速度更快;可以让占用大量处理时间的任务或当前没有进...

Oracle系列之存储过程

涉及到表的处理请参看原表结构与数据Oracle建表插数据等等 判断是否是素数: create or replace procedure isPrime(x number) as flag number:=1; begin if x<2 then dbms_output.put_line('not prime'); else for i in...

kettle内存溢出

ETL工具kettle,在老版设计后,使用新版时,居然发生了内存溢出的错误: 出现: java heap  或者 OutOfMemory等字样  这是kettle分配的内存不足。 在kettle的运行路径中,用文本编辑器打开Spoon.bat,找到: REM ************************************************...

idea修改maven默认配置不生效

1.问题现象 我的idea版本是2019.2的,通过File->Other Setting->Setting for New Projects修改maven的默认配置后,新建项目maven默认配置不生效 2.解决 打开C:Users用户.IntelliJIdea2019.2configoptions下的project.default.xml,添...