【Java/算法/排列】用于产生排列结果的工具类Arranger

【代码】

复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * 用于产生排列结果的工具类
 * 从n个元素中取出m个元素,按照一定的顺序排成一列。得到所有排列的方案
 */
public class Arranger {
    // 保存在内部的对原始元素数组的引用
    private int[] arr;

    // 总计多少元素,此即数组长度
    private final int n;

    // 选多少个
    private final int m;

    // 返回结果
    private List<List<Integer>> results;

    /**
     * 构造函数一
     * 这个构造函数是用于全排列的(n=m=数组长度)
     *
     * @arr 原始元素数组
     */
    public Arranger(int[] arr) {
        this.arr = arr;
        this.n = arr.length;
        this.m = arr.length;

        this.results = new ArrayList<>();
        doArrange(new ArrayList<>());
    }

    /**
     * 构造函数二
     * 这个构造函数是用于部分排列的(m<n=数组长度)
     *
     * @param arr    原始元素数组
     * @param selCnt 选多少个
     */
    public Arranger(int[] arr, int selCnt) {
        this.arr = arr;
        this.n = arr.length;
        this.m = selCnt;
        if (m > n) {
            throw new ArrayIndexOutOfBoundsException("m:" + m + " >n:" + n);
        }

        this.results = new ArrayList<>();
        doArrange(new ArrayList<>());
    }

    /**
     * 使用递归进行全排列,结果放在results中
     *
     * @param initialList 初始链表
     */
    private void doArrange(List<Integer> initialList) {
        List<Integer> innerList = new ArrayList<>(initialList);

        if (m == initialList.size()) {
            results.add(innerList);
        }

        for (int i = 0; i < arr.length; i++) {
            if (innerList.contains(arr[i])) {
                continue;
            }

            innerList.add(arr[i]);
            doArrange(innerList);
            innerList.remove(innerList.size() - 1);
        }
    }

    /**
     * 获得结果链表的引用
     *
     * @return
     */
    public List<List<Integer>> getResults() {
        return results;
    }

    // 测试
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4};
        Arranger arranger = new Arranger(numbers);

        System.out.println("四元素全排列示例:");
        int idx = 0;
        for (List<Integer> re : arranger.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }

        Arranger arranger2 = new Arranger(numbers, 2);
        System.out.println("\n四选二排列示例:");
        idx = 0;
        for (List<Integer> re : arranger2.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }
    }
}
复制代码

【输出】

复制代码
四元素全排列示例:
01.[1, 2, 3, 4]
02.[1, 2, 4, 3]
03.[1, 3, 2, 4]
04.[1, 3, 4, 2]
05.[1, 4, 2, 3]
06.[1, 4, 3, 2]
07.[2, 1, 3, 4]
08.[2, 1, 4, 3]
09.[2, 3, 1, 4]
10.[2, 3, 4, 1]
11.[2, 4, 1, 3]
12.[2, 4, 3, 1]
13.[3, 1, 2, 4]
14.[3, 1, 4, 2]
15.[3, 2, 1, 4]
16.[3, 2, 4, 1]
17.[3, 4, 1, 2]
18.[3, 4, 2, 1]
19.[4, 1, 2, 3]
20.[4, 1, 3, 2]
21.[4, 2, 1, 3]
22.[4, 2, 3, 1]
23.[4, 3, 1, 2]
24.[4, 3, 2, 1]

四选二排列示例:
01.[1, 2]
02.[1, 3]
03.[1, 4]
04.[2, 1]
05.[2, 3]
06.[2, 4]
07.[3, 1]
08.[3, 2]
09.[3, 4]
10.[4, 1]
11.[4, 2]
12.[4, 3]
复制代码

END

posted @   逆火狂飙  阅读(27)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2020-04-29 如何让SpringBoot工程在log/控制台中实时打印MyBatis执行的SQL语句
2020-04-29 雇员信息完全分页方案
2020-04-29 将雇员信息分页显示
2020-04-29 把Employees显示在页面上
2018-04-29 【python】理想论坛爬虫1.08
2014-04-29 使用JRadioButton 示例
2014-04-29 使用JTextArea示例
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示