• JAVA实现组合、排列、重复排列(多层循环)


    1.代码

    package com.hdwang;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * Created by hdwang on 2017-10-25.
     * 组合、排列、可重复排列
     */
    public class CombineAndArrangement {
    
        private static ArrayList<Integer> tmpArr = new ArrayList<>();
        public static void main(String[] args) {
            int [] com = {1,2,3,4};
            int k = 3;
            if(k > com.length || com.length <= 0){
                return ;
            }
            System.out.println("组合结果:");
            combine(0 ,k ,com);
            System.out.println("
    排列结果:");
            arrangement(k,com);
            System.out.println("
    可重复排列结果:");
            repeatableArrangement(k, com);
        }
    
        /**
         * 组合
         * 按一定的顺序取出元素,就是组合,元素个数[C arr.len 3]
         * @param index 元素位置
         * @param k 选取的元素个数
         * @param arr 数组
         */
        public static void combine(int index,int k,int []arr) {
            if(k == 1){
                for (int i = index; i < arr.length; i++) {
                    tmpArr.add(arr[i]);
                    System.out.print(tmpArr.toString() + ",");
                    tmpArr.remove((Object)arr[i]);
                }
            }else if(k > 1){
                for (int i = index; i <= arr.length - k; i++) {
                    tmpArr.add(arr[i]); //tmpArr都是临时性存储一下
                    combine(i + 1,k - 1, arr); //索引右移,内部循环,自然排除已经选择的元素
                    tmpArr.remove((Object)arr[i]); //tmpArr因为是临时存储的,上一个组合找出后就该释放空间,存储下一个元素继续拼接组合了
                }
            }else{
                return ;
            }
        }
    
        /**
         * 排列
         * 按照无序(随机)的方式取出元素,就是排列,元素个数[A arr.len 3]
         * @param k 选取的元素个数
         * @param arr 数组
         */
        public static void arrangement(int k,int []arr){
            if(k == 1){
                for (int i = 0; i < arr.length; i++) {
                    tmpArr.add(arr[i]);
                    System.out.print(tmpArr.toString() + ",");
                    tmpArr.remove((Object)arr[i]);
                }
            }else if(k > 1){
                for (int i = 0; i < arr.length; i++) { //按顺序挑选一个元素
                    tmpArr.add(arr[i]); //添加选到的元素
                    arrangement(k - 1, removeArrayElements(arr, tmpArr.toArray(new Integer[1]))); //没有取过的元素,继续挑选
                    tmpArr.remove((Object)arr[i]);
                }
            }else{
                return ;
            }
        }
    
        /**
         * 可重复排列
         * 类似自己和自己笛卡尔积,类似k层循环拼接的结果,元素个数[arr.len^3]
         * @param k 选取的元素个数(k层循环)
         * @param arr 数组
         */
        public static void repeatableArrangement(int k,int []arr){
            if(k==1){
                for(int i=0;i<arr.length;i++){
                    tmpArr.add(arr[i]);
                    System.out.print(tmpArr.toString() + ",");
                    tmpArr.remove(tmpArr.size()-1); //移除尾部元素
                }
            }else if(k >1){
                for(int i=0;i<arr.length;i++){
                    tmpArr.add(arr[i]);
                    repeatableArrangement(k - 1, arr); //不去重
                    tmpArr.remove(tmpArr.size()-1); //移除尾部元素,不能用remove(Object),因为它会移除头部出现的元素,我们这里需要移除的是尾部元素
                }
            }else{
                return;
            }
        }
    
        /**
         * 移除数组某些元素(不影响原数组)
         * @param arr 数组
         * @param elements 待移除的元素
         * @return 剩余元素组成的新数组
         */
        public static int[] removeArrayElements(int[] arr, Integer... elements){
            List<Integer> remainList = new ArrayList<>(arr.length);
            for(int i=0;i<arr.length;i++){
                boolean find = false;
                for(int j=0;j<elements.length;j++){
                    if(arr[i] == elements[j]){
                        find = true;
                        break;
                    }
                }
                if(!find){ //没有找到的元素保留下来
                    remainList.add(arr[i]);
                }
            }
            int[] remainArray = new int[remainList.size()];
            for(int i=0;i<remainList.size();i++){
                remainArray[i] = remainList.get(i);
            }
            return remainArray;
        }
    }

    2.运行结果

    
    

    组合结果:
    [1, 2, 3],[1, 2, 4],[1, 3, 4],[2, 3, 4],
    排列结果:
    [1, 2, 3],[1, 2, 4],[1, 3, 2],[1, 3, 4],[1, 4, 2],[1, 4, 3],[2, 1, 3],[2, 1, 4],[2, 3, 1],[2, 3, 4],[2, 4, 1],[2, 4, 3],[3, 1, 2],[3, 1, 4],[3, 2, 1],[3, 2, 4],[3, 4, 1],[3, 4, 2],[4, 1, 2],[4, 1, 3],[4, 2, 1],[4, 2, 3],[4, 3, 1],[4, 3, 2],
    可重复排列结果:
    [1, 1, 1],[1, 1, 2],[1, 1, 3],[1, 1, 4],[1, 2, 1],[1, 2, 2],[1, 2, 3],[1, 2, 4],[1, 3, 1],[1, 3, 2],[1, 3, 3],[1, 3, 4],[1, 4, 1],[1, 4, 2],[1, 4, 3],[1, 4, 4],[2, 1, 1],[2, 1, 2],[2, 1, 3],[2, 1, 4],[2, 2, 1],[2, 2, 2],[2, 2, 3],[2, 2, 4],[2, 3, 1],[2, 3, 2],[2, 3, 3],[2, 3, 4],[2, 4, 1],[2, 4, 2],[2, 4, 3],[2, 4, 4],[3, 1, 1],[3, 1, 2],[3, 1, 3],[3, 1, 4],[3, 2, 1],[3, 2, 2],[3, 2, 3],[3, 2, 4],[3, 3, 1],[3, 3, 2],[3, 3, 3],[3, 3, 4],[3, 4, 1],[3, 4, 2],[3, 4, 3],[3, 4, 4],[4, 1, 1],[4, 1, 2],[4, 1, 3],[4, 1, 4],[4, 2, 1],[4, 2, 2],[4, 2, 3],[4, 2, 4],[4, 3, 1],[4, 3, 2],[4, 3, 3],[4, 3, 4],[4, 4, 1],[4, 4, 2],[4, 4, 3],[4, 4, 4],

  • 相关阅读:
    [levelDB] Version Manager
    [levelDB] Compaction
    <Effective Modern C++> 读书笔记
    <Effective Modern C++> 笔记-1-Deducing Type
    水塘抽样(Reservoir Sampling)问题
    【C++工程实践】条件变量
    【c++工程实践】内存模型
    【c++工程实践】智能指针
    【c++工程实践】值语义与右值引用
    分布式系统原理-CAP/2PC/3PC
  • 原文地址:https://www.cnblogs.com/hdwang/p/7732280.html
Copyright © 2020-2023  润新知