字符串的排列

本文介绍了一种使用递归实现字符串所有可能的排列组合的方法,并通过冒泡排序算法对这些组合进行排序,确保输出的有序性和唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
这个问题,难点在于两个地方。
1.如好遍历出所有的可能组合,也就是一个排列组合问题。
2.如何去控制排列顺序问题。
针对以上两个问题,我构造了两个函数,分别解决。
用递归思想去解决排列组合的问题:
传入一个list,这个list里包含了String截取前n个数字的排列组合,传入的str为截取后剩下的字符组成的字符串,这样去递归,出口是当str的长度为1返回集合。

    // 递归思路
    private List<String> getCombaineString(List<String> list,String str){
        if(str.length() == 0)
            return list;
        if(list.size() == 0){
            char c = str.charAt(0);
            List<String> tempList = new ArrayList<String>();
            tempList.add(String.valueOf(c));
            return getCombaineString(tempList, str.substring(1, str.length()));
        }
        char c = str.charAt(0);
        ArrayList<String> tempList = new ArrayList<String>();
        for(String s : list){
            char[] cArr = new char[s.length() + 1];
            for(int i = 0;i < cArr.length;i ++){
                cArr[i] = c;
                for(int j = 0;j < i;j ++){
                    cArr[j] = s.charAt(j);
                }
                for(int j = i + 1;j < cArr.length;j ++){
                    cArr[j] = s.charAt(j - 1);
                }
                tempList.add(String.valueOf(cArr));
            }
        }
        return getCombaineString(tempList, str.substring(1, str.length()));
    }

到此获取的列表为所有排列组合,调用该函数还应该去除掉重复的String:
然后是第二个难点,排序问题

public  ArrayList<String> Permutation(String str) {
        List<String> allCombaineString = getCombaineString(new ArrayList<String>(), str);
        // 去除重复
        ArrayList<String> list = new ArrayList<String>();
        for(String s1 : allCombaineString){
            if(list.contains(s1))
                continue;
            else
                list.add(s1);
        }
        // 处理排序问题
        sortStringByASCII(list);
        return list;
    }

使用冒泡排序,分别去比较每个字符串的相对位置,比较方法为以此比较高位的ASCII码的大小,用一个布尔值去控制交换。


    // 排序问题,冒泡
    private static void sortStringByASCII(List<String> list){
        for(int i = 0;i < list.size() - 1;i ++){
            for(int j = 0;j < list.size() - i - 1;j ++){
                // 比较每一位ASCII
                boolean isChangePosition = false;// 布尔变量控制是否完成交换
                for(int position = 0;position < (list.size() != 0 ? list.get(0).length() : 0);position ++){
                    System.out.println(list.get(j + 1).charAt(position) + " 和 " + list.get(j).charAt(position) + " 比较 ");//
                    if(list.get(j + 1).charAt(position) < list.get(j).charAt(position)){
                        String temp = list.get(j + 1);
                        list.set(j + 1, list.get(j));
                        list.set(j, temp);
                        isChangePosition = true;
                    } else if(list.get(j + 1).charAt(position) > list.get(j).charAt(position))
                        isChangePosition = true;
                    if(isChangePosition)
                        break;
                }
            }
        }
    }

完整代码

public static void main(String[] args) {
//      System.out.println(Permutation("abcdefg"));
        /*
         * 

        String s = "sagfsag";
        if(Permutation(s).size() == getNumberOfCombaine(s))
            System.out.println("个数正确");
        else
            System.out.println("数量不对");

        boolean isRepeat = false;
        for(String str : Permutation(s)){
            int count = 0;
            for(String s2 :Permutation(s)){
                if(s2.equals(str))
                    count ++;
            }
            if(count >= 2)
                isRepeat = true;
        }
        if(isRepeat){
            System.out.println("存在重复");
        } else {
            System.out.println("不重复");
        }
        */
        System.out.println(Permutation("abc"));
    }

    public static ArrayList<String> Permutation(String str) {
        List<String> allCombaineString = getCombaineString(new ArrayList<String>(), str);
        // 去除重复
        ArrayList<String> list = new ArrayList<String>();
        for(String s1 : allCombaineString){
            if(list.contains(s1))
                continue;
            else
                list.add(s1);
        }
        // 处理排序
        sortStringByASCII(list);
        return list;
    }

    // 排序问题,冒泡
    private static void sortStringByASCII(List<String> list){
        for(int i = 0;i < list.size() - 1;i ++){
            for(int j = 0;j < list.size() - i - 1;j ++){
                // 比较每一位ASCII
                boolean isChangePosition = false;// 布尔变量控制是否完成交换
                for(int position = 0;position < (list.size() != 0 ? list.get(0).length() : 0);position ++){

                    if(list.get(j + 1).charAt(position) < list.get(j).charAt(position)){
                        String temp = list.get(j + 1);
                        list.set(j + 1, list.get(j));
                        list.set(j, temp);
                        isChangePosition = true;
                    } else if(list.get(j + 1).charAt(position) > list.get(j).charAt(position))
                        isChangePosition = true;
                    if(isChangePosition)
                        break;
                }
            }
        }
    }

    // 计算出可能的组合方式
    private static int getNumberOfCombaine(String str){
        // 求出相同的个数
        Map<Character,Integer> map = new HashMap<Character,Integer>();
        for(int i = 0;i < str.length();i ++){
            char c = str.charAt(i);
            if(map.keySet().contains(c))
                continue;
            int count = 0;
            for(int j = 0;j < str.length();j ++){
                if(c == str.charAt(j))
                    count ++;
                }
            if(count >= 2)
                map.put(c, count);
            }
        // 不考虑重复的排列可能
        int sum = 1;
        for(int i =1;i <= str.length();i ++){
            sum *= i;
        }
        // 排除重复的数字
        for(Character c : map.keySet()){
            for(int i = 1;i <= map.get(c);i ++){
                sum /= i;
            }
        }
        return sum;
    }

    // 递归思路
    private static List<String> getCombaineString(List<String> list,String str){
        if(str.length() == 0)
            return list;
        if(list.size() == 0){
            char c = str.charAt(0);
            List<String> tempList = new ArrayList<String>();
            tempList.add(String.valueOf(c));
            return getCombaineString(tempList, str.substring(1, str.length()));
        }
        char c = str.charAt(0);
        ArrayList<String> tempList = new ArrayList<String>();
        for(String s : list){
            char[] cArr = new char[s.length() + 1];
            for(int i = 0;i < cArr.length;i ++){
                cArr[i] = c;
                for(int j = 0;j < i;j ++){
                    cArr[j] = s.charAt(j);
                }
                for(int j = i + 1;j < cArr.length;j ++){
                    cArr[j] = s.charAt(j - 1);
                }
                tempList.add(String.valueOf(cArr));
            }
        }
        return getCombaineString(tempList, str.substring(1, str.length()));
    }

运行结果:[abc, acb, bac, bca, cab, cba]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值