1. 程式人生 > >Java 排列組合和集合的交併差以及遞迴

Java 排列組合和集合的交併差以及遞迴

最近正在做一個專案寫遞迴寫的不少,遞迴真的是Java中非常常見的,但是遞迴寫的好不好也是取決於思維是否清晰。多思考自己的程式碼,儘量讓程式碼變得優雅和可讀性。

按照慣例推薦一首歌曲。我們的時光--趙雷

本文主要介紹三個方面的內容

1.Java中的排列組合

2.集合中的交併差(google Guava 和apache commons collectionsutil 都是可以的)

3.關於寫遞迴時原則

mavne的依賴  

<Dependecy>

<groupId>org.raistlic.lib</groupId>

<artifactId>commons-core</artifactId>

<version>1.4</version>

</Dependecy>

import org.raistlic.common.permutation.Combination;
import org.raistlic.common.permutation.Permutation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * ${DESCRIPTION}
 *
 * @author mengxp
 * @version 1.0
 * @create 2018-01-15 21:05
 **/
public class JoneTest {


    public static final Logger CombineArithmeticLOG = LoggerFactory.getLogger(JoneTest.class);
    public static final String ARITHMETIC_CONNECT_SPLIT = "\\$";
    public static final String ARITHMETIC_CONNECT = "$";


    /**
     * 對集合中的元素進行全排列
     * [1, 2, 3]
      [1, 3, 2]
      [2, 1, 3]
      [2, 3, 1]
      [3, 1, 2]
      [3, 2, 1]
     */
    public void testPermutationAll(){
        Permutation<String> of = Permutation.of(Arrays.asList("1", "2", "3"));
        for (List<String> list : of) {
            System.out.println(list);
        }
    }

    /**
     * 對集合中的任取numberToPick個數進行全排列
     */
    public void testPermutationOfDefine(){
        int cout = 0;
        for (List<Integer> list : Permutation.of(Arrays.asList(1, 2, 3, 4, 5), 3)) {
            cout++;
            System.out.println(list);
        }
        System.out.println(cout);
    }

    /**
     * 取出集合中的任意個數 組合計算
     */
    public void testCombinationOfDefine(){
        for (List<Integer> list : Combination.of(Arrays.asList(1, 2, 3, 4, 5), 3))
            System.out.println(list);
    }


    public static void main(String[] args) {
        HashSet<String> result=new HashSet();
        exeMain(true,2,Arrays.asList("a","b","c"),result);
        System.out.println("xxxx");
    }


    /**
     *
     * @param isFlag        採用排列或者組合的方式
     * @param combieCounter 子集合的組合方式
     * @param sourece       資料來源
     * @param resultSets    返回的結果集
     * @return  mengxp
     */
    public static Set<String> exeMain(boolean isFlag, int combieCounter, List<String> sourece, Set<String> resultSets) {
        if (sourece == null) {
            CombineArithmeticLOG.error("sourece is null...");
            return resultSets;
        }
        if (sourece != null || sourece.size() == 0) {
            if (combieCounter > sourece.size()) {
                CombineArithmeticLOG.error("combineCounter must be < source size...");
                return resultSets;
            }
        }
        if (isFlag) {//TODO 全排列
            List<List<String>> pl = RankArithmetic.pl(sourece);
            for (int i = 0; i < pl.size(); i++) {
                select(combieCounter, pl.get(i), resultSets);
            }
        } else {
            //TODO 全組合
            select(combieCounter, sourece, resultSets);
        }
        return resultSets;
    }

    private static void select(int k, List<String> sources, Set<String> resultSet) {
        String[] result = new String[k];
        subselect(0, 1, result, k, sources, resultSet);
    }

    /**
     * 遞迴演算法
     * @param head
     * @param index
     * @param r
     * @param k
     */
    private static void subselect(int head, int index, String[] r, int k, List<String> sources, Set<String> resultSet) {
        for (int i = head; i < sources.size() + index - k; i++) {
            if (index < k) {
                r[index - 1] = sources.get(i);
                subselect(i + 1, index + 1, r, k, sources, resultSet);
            } else if (index == k) {
                r[index - 1] = sources.get(i);
                String content = "";
                for (int j = 0; j < r.length; j++) {
                    String a = r[j];
                    content = content + ARITHMETIC_CONNECT + a;
                }
                content = content.replaceFirst(ARITHMETIC_CONNECT_SPLIT, "");
                resultSet.add(content);
                subselect(i + 1, index + 1, r, k, sources, resultSet);
            } else {
                return;
            }
        }
    }


}

import java.util.LinkedList;
import java.util.List;


/**
 * Created by mengxp on 2017/8/18.
 */
public class RankArithmetic {

    /**
     * 得到全排列的方法
     * @param data  存放要排列的各個元素
     * @return List<List<String>> 結果中的每一個List就是一種可能的排列
     */
    public static List<List<String>> pl(List<String> data){

        if(data.size()==1){
            // 如果data中只有一個元素,那麼直接得到它的全排列
            List<List<String>> result= new LinkedList<List<String>>();
            List<String> p = new LinkedList<>();
            p.add(data.get(0));
            result.add(p);
            return result;
        }else{
            // 否則,去除第一個元素,然後得到剩下的 n-1 個元素的全排列,第一個元素插入到每一種排列中的相應位置上就可以得到所有元素的全排列了
            // 也就是說, n-1 個元素的全排列中的每一種排列又可以衍生出 n 種排列
            String first = data.get(0);
            List<String> remainList = data.subList(1, data.size());
            List<List<String>> remainPl = pl(remainList);

            List<List<String>> result= new LinkedList<List<String>>();
            for(int i=0;i<remainPl.size();i++){

                List<String> thisOne = remainPl.get(i);
                for(int j=0;j<=thisOne.size();j++){

                    List<String> copyOne = new LinkedList<>(thisOne);
                    copyOne.add(j,first);
                    result.add(copyOne);
                }
            }
            return result;
        }
    }
}
2.集合的交併差和集合的Split,將集合按照大小劃分,推薦使用Guava中的Sets Lists等 下面是apachecommons的Demo
package matrixOnto.deal.Util;


import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Created by mengxp on 2017/9/27.
 */
public class CollectionPower {
    private static Logger logger = LoggerFactory.getLogger(CollectionPower.class);

    public static void main(String[] args) {
        String[] arrA = new String[100000];
        String[] arrB = new String[100000];
        for (int i=0;i<100000;i++) {
            int i1 = new Random().nextInt(1000000);
            arrA[i]=i1+"";
            int i2 = new Random().nextInt(1000000);
            arrB[i]=i2+"";
        }
   /*     String[] arrA = new String[]{"1", "3", "5", "6"};
        String[] arrB = new String[]{"2", "3", "7", "8"};*/
        long startTime=System.currentTimeMillis()/1000;
        String union = new CollectionPower().collectionUnion(arrA, arrB);
        //String interSection = new CollectionPower().collectionInterSection(arrA, arrB);
        String disjunction = new CollectionPower().collectionDisjunction(arrA, arrB);
        String subtract = new CollectionPower().collectionSubtract(arrA, arrB);
        long endTime=System.currentTimeMillis()/1000;
     /*   System.out.println("union: [" + union + "]");
        System.out.println("interSection: [" + interSection + "]");
        System.out.println("disjunction: [" + disjunction + "]");
        System.out.println("subtract: [" + subtract + "]");*/
        System.out.println("All Spend Time is :["+(endTime-startTime)+"]");
    }


    /**
     * Union action.會去重
     *
     * @param arrayA
     * @param arrayB
     * @return
     */
    public static String collectionUnion(String[] arrayA, String[] arrayB) {
        String arrayC = "";
        try {
            List<String> a = Arrays.asList(arrayA);
            List<String> b = Arrays.asList(arrayB);
            Collection union = CollectionUtils.union(a, b);
            arrayC = union.toString();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("execute union action failed.....");
        }
        return arrayC;

    }


    /**
     * 交集
     *
     * @param arrayA
     * @param arrayB
     * @return
     */
    public static List<String> collectionInterSection(String[] arrayA, String[] arrayB) {
      List<String> list=new ArrayList<>();
        try {
            List<String> a = Arrays.asList(arrayA);
            List<String> b = Arrays.asList(arrayB);
            Collection union = CollectionUtils.intersection(a, b);
            list.addAll(union);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("execute InterSection action failed.....");
        }
        return list;
    }


    /**
     * union出去交集的集合
     *
     * @param arrayA
     * @param arrayB
     * @return
     */
    public static String collectionDisjunction(String[] arrayA, String[] arrayB) {
        String arrayC = "";
        try {
            List<String> a = Arrays.asList(arrayA);
            List<String> b = Arrays.asList(arrayB);
            Collection union = CollectionUtils.disjunction(a, b);
            arrayC = union.toString();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("execute Disjunction action failed.....");
        }
        return arrayC;
    }


    /**
     * 集合(A-交集)
     *
     * @param arrayA
     * @param arrayB
     * @return
     */
    public static String collectionSubtract(String[] arrayA, String[] arrayB) {
        String arrayC = "";
        try {
            List<String> a = Arrays.asList(arrayA);
            List<String> b = Arrays.asList(arrayB);
            Collection union = CollectionUtils.subtract(a, b);
            arrayC = union.toString();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("execute subtract action failed.....");
        }
        return arrayC;
    }
}

package matrixOnto.deal;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import matrixOnto.preparse.HbaseObj;

import javax.annotation.Nullable;
import java.util.List;

/**
 * Created by mengxp on 2017/12/26.
 */
public class GoogleCollectionsUtils<I,R> {

    public static final String TYPE_VALUE_COMBINE_STR="_";

    /**
     transform.toImmutableList();
     transform.toArray();
     transform.toImmutableSet()
     * @param inputs
     * @param function
     * @param <I>
     * @return 傳入Fucntion進行型別轉化
     */
    public  <I> FluentIterable<R> commonTransFunction(Iterable<I> inputs, Function<I,R> function){
        FluentIterable<R> transform = FluentIterable.from(inputs).transform(function);
        return transform;
    }

    /**
     * 將集合進行拆分
     * @param inputs
     * @param collectionSize 指定每個集合的最大的size
     * @param <I>
     * @return
     */
    public static <I> List<List<I>> listSplit(List<I> inputs,int collectionSize){
        List<List<I>> partition = Lists.partition(inputs, collectionSize);
        return partition;
    }

    public static Function<HbaseObj, String> Function_Type_Value = new Function<HbaseObj, String>() {
            @Nullable
            @Override
            public String apply(@Nullable HbaseObj hbaseObj) {
                String hbaseObjId = hbaseObj.getId();
                String hbaseObjType = hbaseObj.getType();
                String id = Joiner.on(TYPE_VALUE_COMBINE_STR).join(hbaseObjType, hbaseObjId);
                return id;
            }

            @Override
            public boolean equals(@Nullable Object o) {
                return false;
            }
        };



}


3.關於遞迴演算法 

1.返回值Void

2.有層次或者無層遞迴

3.寫遞迴時,必須把輸入,輸出定義清楚。

/**
     
     * @param input
     * @param infos
     * @param filterVo
     */
    private void recursionGraphInfos(RecursionExtendVo input, List<GraphInfo> infos, ExtendsFilterVo filterVo) {
        RECURSIONEXTENDANALYSISFUTURELOG.info("Current Run Recursion level {{}} ",filterVo.getRecursionLevel());
        if (filterVo.getRecursionLevel() == levelCondition) {
            //達到了遞迴的次數
            return;
        }
        RecursionExtendVo recursionExtendVo = queryOneByMain(input, infos, filterVo);
        recursionGraphInfos(recursionExtendVo, infos, filterVo);
    }


    /**
     *
     * @param input
     * @param infos
     * @param filterVo
     * @return
     */
    private RecursionExtendVo queryOneByMain(RecursionExtendVo input, List<GraphInfo> infos, ExtendsFilterVo filterVo) {
        filterVo = filterVo.leverDecrease(filterVo);
        HashMultimap<String, String> hashMultimap = input.getHashMultimap();
        Collection<String> values = hashMultimap.values();

        HashMultimap<String, String> recusionMap = HashMultimap.create();
        if (values.size() == 0) {
            return input.setHashMultimap(recusionMap);
        }
        for (String dealNum : values) {
            GraphInfo infoByTimeFilter = getInfoByTimeFilter(dealNum, filterVo, recusionMap);
            infos.add(infoByTimeFilter);
        }
        return input.setHashMultimap(recusionMap);
    }


    private GraphInfo getInfoByTimeFilter(String dhhm, ExtendsFilterVo vo, HashMultimap<String, String> recusionMap) {
        //比如dhhm=A  recusionMap={A->A1,A->A2,A->A3,A->A4}
        String rowKey = BaseQueryBusiness.getMainRowKey("DHHM", dhhm);
        GraphInfo result=new GraphInfo();
        result.setEdgeSet(new HashSet<Edge>()).setVertexSet(new HashSet<Vertex>());
         try {
             result= commonByRecusion(table, gson, RECURSIONEXTENDANALYSISFUTURELOG, Bytes.toBytes(rowKey), OntologyServerConstants.MAIN_STORM_ENEVT, recusionMap,isFilter,vo);
        } catch (IOException e) {
            DealUtils.LogError(e, RECURSIONEXTENDANALYSISFUTURELOG);
        }
        return result;
    }




相關推薦

Java 排列組合集合交併以及

最近正在做一個專案寫遞迴寫的不少,遞迴真的是Java中非常常見的,但是遞迴寫的好不好也是取決於思維是否清晰。多思考自己的程式碼,儘量讓程式碼變得優雅和可讀性。 按照慣例推薦一首歌曲。我們的時光--趙雷 本文主要介紹三個方面的內容 1.Java中的排列組合 2.集合中的交併差

[java]氣泡排序的常規、改進以及實現

package sort_book_datastruction; import java.util.Arrays; /** * 氣泡排序; * @author Administrator * */ public class BubbleSort {

Java 數組集合

控制 div string size arrays類 class pri new 對象 一、數組  java.util.Arrays類提供了操作數組的一些方法,如排序、轉集合等等 二、集合 三、數組集合的相互轉化:   1、數組轉集合: String[]

java 類方法實例方法 以及 類變量實例變量

ati 所有 ron 變量 執行 成員 退出 strong 修飾 類體中的方法分為實例方法和類方法兩種,用static修飾的是類方法 類方法: 對於類中的類方法,在該類被加載到內存時,就分配了相應的入口地址。從而類方法不僅可以被類創建的任何對象調用執行,也可以直接通過類名調

面試過程中的排列組合趣味性題目二

面試過程中的排列組合和趣味性題目 感想 problem 31 problem 32 learning problem 33 problem 34 problem 35

面試過程中的排列組合趣味性題目一

面試過程中的排列組合和趣味性題目 感想 problem 1 problem 2 problem 3 problem 4 problem 5 problem 6 problem 7 problem

java排列組合實現

import java.util.Scanner; public class combination { public static int k1=0; //計數k1 public static int k2=0;

java記憶體溢位棧溢位例項以及記憶體溢位記憶體洩露的區別

記憶體溢位和記憶體洩露的區別:記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了一個integer,但給它存了lo

java排列組合演算法(M選N)

從M長度的容器中每次選取N個元素 舉例,從(a,b,c,d,e)中取兩個元素,則為(ab) (ac) (ad)(ae)(bc)(bd)(be)(cd)(ce)(de) import java.util.ArrayList; import java.uti

JAVA中REPLACEREPLACEALL的區別 以及一些特殊字元替換

replace和replaceAll是JAVA中常用的替換字元的方法,它們的區別是:  1)replace的引數是char和CharSequence,即可以支援字元的替換,也支援字串的替換(CharSequence即字串序列的意思,說白了也就是字串);  2)replaceAll的引數是regex,即基於規

Java中陣列集合容器的剖析

java中常用的儲存容器就是陣列的集合,每種容器儲存的形式和結構又有所不同。 陣列,是最基礎的容器,在建立陣列的時候有三種方式分別如下: int[] arr = new int[5]; int[] arr = new String[]{1,2,3,4,5}; in

Java中ProcessRuntime()使用,以及呼叫cmd命令阻塞在process.waitfor( )的問題解決

轉自:http://249wangmang.blog.163.com/blog/static/52630765201261334351635/ 最近在java中呼叫perl程式,由於perl中使用斯坦福分詞器,有很多控制檯輸出,導致一直阻塞在process.waitfor

排列組合回溯演算法-面試題

public void solveSudoku(char[][] board) { ArrayList<ArrayList<Integer>> emptyLocations= new ArrayList<ArrayList<Int

Java中陣列集合的區別

陣列:大小固定,同一個陣列中只能存放同一個型別的資料。 集合:可以運算元目和型別不固定的一組資料。所有的JAVA集合都位於 java.util包中,JAVA集合只能存放引用型別的的資料,不能存放基本資

Java中關於==equal的區別以及equals()方法重寫

例子i: string1="aaa"; string2="aaa"; String string3=new String("aaa"); String string4=new String("aaa"); string1==string2 // true; . string1.equals(string2)

Java基礎入門五)之方法以及歸算法

存在 兼容 直接 elf 推薦 1.8 可讀性 do..while 方法體 一.方法 1.1 什麽是方法 java中的方法類似於其他語言中的函數 是一段用來完成特定功能的代碼片段 1.2 為什麽要聲明方法

Atitit 壓縮檔案zip總結 注意孔目錄 以及 目錄 /springbootUpload/src/springbootUploadPkg/ZipUtilCompressPart.java

Atitit 壓縮檔案zip總結   注意孔目錄 以及 遞迴目錄   /springbootUpload/src/springbootUploadPkg/ZipUtilCompressPart.java   File file 

已知兩個連結串列head1 head2 各自有序,請把它們合併成一個連結串列依然有序。使用非方法以及方法。

首先介紹非遞迴方法。因為兩個連結串列head1 和head2都是有序的,所以我們只需要找把較短連結串列的各個元素有序的插入到較長的連結串列之中就可以了。 原始碼如下: 1 node* insert_node(node *head, node *item) //head != NULL 2 { 3 node

【資料結構】二叉樹的建立遍歷(非

該程式使用的是遞迴地建立方法,以及非遞迴的遍歷演算法 執行環境:Dev-C++ #include <stdio.h> #include <stdlib.h> typedef struct node{ char data; struct node *lchild

Java實現斐波那契數列(、遍歷、矩陣)

什麼是斐波那契數列 其實很簡單,可以理解為: F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*) 比如這樣一個數列:1、1、2、3、5、8、13、21、34、…… 有興趣可以看百度百科 下面我們就來實現,給定一個n,求f(n)的值