• java全排列从普通循环到递归


      首先是给出一步步交换的过程,例如abc三个字母的全排列,思路就是先a在前得到abc,交换后边两个字母得到acb再交换回来abc,然后b在前,最后c在前,依次交换后边的字母输出,然后交换回abc。代码如下:

    public class TestDemo3 {
        public static void trans( String str ) {
            char[] arr = str.toCharArray();
            permute(arr,3);
        }
        
        public static void permute( char[] arr, int a ) {
         //a在首字母
            swap(arr,arr.length-3,arr.length-3);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            System.out.print(" ");
            swap(arr,arr.length-2,arr.length-1);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            swap(arr,arr.length-2,arr.length-1);
            swap(arr,arr.length-3,arr.length-3);
            System.out.println();
            //b在首字母
            swap(arr,arr.length-3,arr.length-2);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            System.out.print(" ");
            swap(arr,arr.length-2,arr.length-1);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            swap(arr,arr.length-2,arr.length-1);
            swap(arr,arr.length-3,arr.length-2);
            System.out.println();
            //c在首字母
            swap(arr,arr.length-3,arr.length-1);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            System.out.print(" ");
            swap(arr,arr.length-2,arr.length-1);
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]);
            }
            swap(arr,arr.length-2,arr.length-1);
            swap(arr,arr.length-3,arr.length-1);
            
        public static void swap( char[] arr, int a, int b ) {
            char temp;
            temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
        
        public static void main( String[] args ) {
            trans("abcd");
        }
    }

      接下来对重复的代码进行重构,重复的部分可以用循环替代,代码如下:

    public class TestDemo3 {
        public static void trans( String str ) {
            char[] arr = str.toCharArray();
            permute(arr,0);
        }
        
        public static void permute( char[] arr, int a ) {
            for(int j=a;j<arr.length;j++) {
                swap(arr,a,j);
                for(int k=0;k<arr.length;k++) {
                    System.out.print(arr[k]);
                }
                System.out.print(" ");
                swap(arr,arr.length-2,arr.length-1);
                for(int k=0;k<arr.length;k++) {
                    System.out.print(arr[k]);
                }
                System.out.println();
                swap(arr,arr.length-2,arr.length-1);
                swap(arr,a,j);
            }
        }
        
        public static void swap( char[] arr, int a, int b ) {
            char temp;
            temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
        
        public static void main( String[] args ) {
            trans("abc");
        }
    }

      对于4个字符的字符串,显然以上方法不行,利用循环嵌套可以解决,思路就是,先a在前,按照交换3个字符的字符串的方式交换bcd,再将a与bcd依次交换进行排列。代码如下:

    public class TestDemo3 {
        public static void trans( String str ) {
            char[] arr = str.toCharArray();
            permute(arr,0);
        }
        
        public static void permute( char[] arr, int a ) {
            for(int i=a;i<arr.length;i++) {
                swap(arr,a,i);
                for(int j=a+1;j<arr.length;j++) {
                    swap(arr,a+1,j);
                    for(int k=0;k<arr.length;k++) {
                        System.out.print(arr[k]);
                    }
                    System.out.print(" ");
                    swap(arr,arr.length-2,arr.length-1);
                    for(int k=0;k<arr.length;k++) {
                        System.out.print(arr[k]);
                    }
                    System.out.println();
                    swap(arr,arr.length-2,arr.length-1);
                    swap(arr,a+1,j);
                }
                swap(arr,a,i);
            }
        }
        
        public static void swap( char[] arr, int a, int b ) {
            char temp;
            temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
        
        public static void main( String[] args ) {
            trans("abcd");
        }
    }

      从3个字符的字符串全排列到4个字符的字符串全排列,可以明显的看出来字符串的全排列是一个递归问题,n个字符的字符串全排列相当于有1*2*3*4*5...*n种输出结果,那么可以通过递归来解决n个字符的字符串全排列。首先,由三个字符到四个的全排列,可以发现是在三个字符的基础上外嵌一个for循环,循环4次,并且,每次将首个字母依次替换。利用递归实现嵌套的循环,输出当a=arr.length-1时的数组。

    代码如下:

    public class TestDemo3 {
        public static int count;
        public static void trans( String str ) {
            char[] arr = str.toCharArray();
            permute(arr,0);
        }
        
        public static void permute( char[] arr, int a ) {
            if(a==arr.length-1) {
                for(int k=0;k<arr.length;k++) {
                    System.out.print(arr[k]);
                }
                count++;
                System.out.print(" ");
            }
            if(a==1) {
                System.out.println();
            }
            
            
            for(int i=a;i<arr.length;i++) {
                swap(arr,a,i);
                permute(arr,a+1);
                swap(arr,a,i);
            }
        }
        
        public static void swap( char[] arr, int a, int b ) {
            char temp;
            temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
        
        public static void main( String[] args ) {
            trans("abcdf");
            System.out.println();
            System.out.println(count);
        }
    }

      这是一个5字符的字符串全排列,从三个和四个字符的字符串全排列变化中我们可以发现如何去将循环转换为递归。其中递归执行过程大致如下(三个字符):

    i=0
    swap (arr,0,0)
    permute(arr,1)
        i=1
        swap (arr,1,1)
        permute(arr,2)
            i=2 
            swap (arr,2,2)
            swap (arr,2,2)
        swap (arr,1,1)
        i=2
        swap (arr,1,2)
        permute(arr,2)
            i=2
            swap (arr,2,2)
            swap (arr,2,2)
        swap (arr,1,2)
    swap (arr,0,0)
    i=1
    swap (arr,0,1)
    permute(arr,1)
        i=1
        swap (arr,1,1)
        permute(arr,2)
            i=2
            swap (arr,2,2)
            swap (arr,2,2)
            swap (arr,1,1)
        i=2
        swap 1 2
        permute(arr,2)
            i=2
            swap (arr,2,2)
            swap (arr,2,2)
        swap (arr,1,2)
    swap (arr,0,1)
    .
    .
    .

     

  • 相关阅读:
    js--事件
    js之table操作
    2019年目标
    history.back返回后输入框值丢失问题
    C++ 工程师养成 每日一题4.5 (迭代器遍历)
    C++ 工程师养成 每日一题fourth (reverse的使用)
    C++ 工程师养成 每日一题third (子数列排序)
    C++工程师养成 每日一题(string使用)
    C++工程师养成 每日一题(vector使用)
    运算符优先级
  • 原文地址:https://www.cnblogs.com/mengxinteriri/p/11094806.html
Copyright © 2020-2023  润新知