全排列算法实现

全排列算法实现

方法1:插入法,取字符串的第一个元素放到集合res,后面将字符串的其余元素依次插入到当前集合res的前,中,后。

import java.util.ArrayList;

public class FullPermutation1 {
    public static ArrayList<String> f(String s){
        ArrayList<String> res = new ArrayList<>() ;
        res.add("" + s.charAt(0)) ;
        for(int i=1; i<s.length(); i++){
            char c = s.charAt(i) ;
            ArrayList<String> res1 = new ArrayList<>() ;
            for(String s1 : res){
                String str = c + s1 ; //插入到当前集合元素的前方
                res1.add(str) ;
                str = s1 + c ; //插入到当前集合元素的后方
                res1.add(str) ;
                for(int j=1;j<s1.length(); j++){ //插入到当前集合元素的中间
                    str = s1.substring(0,j) + c + s1.substring(j) ;
                    res1.add(str) ;
                }
            }
            res = res1 ; //每插入完成一个元素后更新集合
        }
        return res ;
    }
    public static void main(String[] args){
        String s = "abcd" ;
        System.out.println("全排列的种类有:" + f(s).size()) ;
        for(String result : f(s)){
            System.out.println(result) ;
        }
    }
}

方法2:交换法:每个元素尝试着放到头部,每条支路完成后,要回溯恢复为之前的情况


import java.util.ArrayList;
import java.util.Iterator;

public class FullPermutation2 {
    public static ArrayList<String> result = new ArrayList<>() ;
    public static void swap(char [] arr, int i, int j){
        char temp = arr[i] ;
        arr[i] = arr[j] ;
        arr[j] = temp ;
    }
    public static void getPermutationCore(char [] arr, int k){
        if(k == arr.length){
            result.add(new String(arr)) ;
        }
        for(int i=k; i<arr.length; i++){
            swap(arr, i, k) ;
            getPermutationCore(arr, k+1) ;
            swap(arr, i, k) ; //回溯
        }
    }
    public static ArrayList<String> getPermutation(String s){
        char [] res = s.toCharArray() ;
        getPermutationCore(res, 0) ;
        return result ;
    }
    public static void main(String[] args){
        String s = "abcd" ;
        ArrayList<String> result = getPermutation(s) ;
        Iterator iterator = result.iterator() ;
        while(iterator.hasNext()){
            System.out.println(iterator.next()) ;
        }
    }
}

方法3:前缀法,此方法更使适用,可以输出按字符串升序的全排列,更能满足需求。

public class FullPermutation3 {
    public static int count = 0 ;
    public static long factorial(long n){//求阶乘
        long result = 1 ;
        for(long i=1; i<=n; i++){
            result *= i ;
        }
        return result ;
    }
    public static void getPermutation(String prefix, char [] arr){ //前缀法求全排列
        if(prefix.length() == arr.length){
            count ++ ;
            System.out.println(prefix) ;
            if(count == factorial(arr.length)){ //所有全排列输出完毕,则退出
                System.exit(0) ;
            }
        }
        for(int i=0; i<arr.length; i++){
            char c = arr[i] ;
            if(count(arr,c) > count(prefix.toCharArray(),c)){
                getPermutation(prefix+c, arr) ; //每个字符分别作为前缀依次递归下去
            }
        }
    }
    public static int count(char [] arr, char ch){ //计算字符在字符数组中出现的次数
        int sum =  0;
        for(int i=0; i<arr.length; i++){
            if(arr[i] == ch){
                sum ++ ;
            }
        }
        return sum ;
    }
    public static void main(String[] args){
        String s = "abcd" ;
        getPermutation("",s.toCharArray());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值