【Java/算法/排列】ABCDE五人排一排,如果AB必相邻且B在A的右边,那么不同的排法有几种?

【数学解法】

AB捆绑,内部不再排序,与CDE全排,得A44=24种排法。

【代码解法】

Fiveman类:

package test230425;

import java.util.List;

import arrange.Arranger;

/**
 * ABCDE五人排一排,如果AB必相邻且B在A的右边,那么不同的排法有几种?列举出这些排法。
 */
public class Fiveman {
    public static void main(String[] args) {
        final String[] names = { "AB", "C", "D", "E" };
        final int[] arr = { 0, 1, 2, 3 };

        Arranger arranger = new Arranger(arr);
        int idx = 0;
        for (List<Integer> res : arranger.getResults()) {
            String name = "";
            for (int i = 0; i < names.length; i++) {
                name += names[res.get(i)];
            }

            System.out.println(String.format("%02d", ++idx) + "." + name);
        }
    }
}

Arranger类:

package arrange;

import java.util.ArrayList;
import java.util.List;

/**
 * 用于产生数组全排列结果的工具类
 * @since 2023/4/21
 */
public class Arranger {
    // 保存在内部的原始元素数组的引用
    private int[] rawArr;

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

    /**
     * 构造函数
     * 
     * @param raws 原始元素数组
     */
    public Arranger(int[] raws) {
        rawArr = raws;
        results = new ArrayList<>();

        doArrange(new ArrayList<>());
    }

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

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

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

            innerList.add(rawArr[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,5};
        Arranger arranger = new Arranger(numbers);

        int idx = 0;
        for (List<Integer> re : arranger.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }
    }
}

【排序结果】

01.ABCDE
02.ABCED
03.ABDCE
04.ABDEC
05.ABECD
06.ABEDC
07.CABDE
08.CABED
09.CDABE
10.CDEAB
11.CEABD
12.CEDAB
13.DABCE
14.DABEC
15.DCABE
16.DCEAB
17.DEABC
18.DECAB
19.EABCD
20.EABDC
21.ECABD
22.ECDAB
23.EDABC
24.EDCAB

END

 

posted @ 2023-04-25 21:06  逆火狂飙  阅读(42)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东