獲取集合的子集合,子集合必須滿足指定個數,而且不能重複 (java代碼實現)

 

package ceshi.About8;

import java.util.*;
import java.util.stream.Collectors;

public class LamdaTest {
    private  static  String getA(){return "a";}

    public static void main(String[] args) {

        List<NodeTest> nodeTests = Arrays.asList(
                new NodeTest("A",2.11,true),
                new NodeTest("B",2.00,true),
                new NodeTest("G",2.11,false),
                new NodeTest("G",1.10,false),
                new NodeTest("C",2.10,true),
                new NodeTest("D",2.10,true),
                new NodeTest("E",2.10,false),
                new NodeTest("F",2.10,false)

        );
        // 30選15中的15
        int selection = 6;


        long start1 = System.currentTimeMillis();
        ArrayList<List<NodeTest>> result1 =  getResultList(nodeTests,selection);
        long end1 = System.currentTimeMillis();
        System.out.println("1所用時間爲:" +(end1 - start1));

    }

    /**
     * 獲取幾選幾的所有集合
     *
     * @param nodeTests 集合
     * @selection 策略 幾選幾
     */
    public static ArrayList<List<NodeTest>> getResultList (List<NodeTest> nodeTests,int selection){

        //獲取標識爲false的組合
        List<NodeTest> allFasleCol = nodeTests.stream().filter((x)->x.getFlag()==false).collect(Collectors.toList());
        //獲取標識爲true的組合
        List<NodeTest> allTrueCol = nodeTests.stream().filter((x)->x.getFlag()==true).collect(Collectors.toList());

        //爲false的必須有幾個
        int selectionFlase = selection - allTrueCol.size();
        ArrayList<List<NodeTest>>  allChildrenFasleCol = getFalseAllChildren(allFasleCol,selectionFlase);

        ArrayList<List<NodeTest>>  result = new ArrayList<>();
        for(List<NodeTest> nodesList :allChildrenFasleCol){
            nodesList.addAll(allTrueCol);
            result.add(nodesList);
            System.out.println("子集:"+nodesList);
        }
        return result;
    }

    /**
     * 獲取子集個數爲selection所有集合,去重
     *
     * @param nodesLlist 集合
     * @param selection 子集中的個數
     */
    public static ArrayList<List<NodeTest>> getFalseAllChildren(List<NodeTest> nodesLlist,int selection){
        ArrayList<List<NodeTest>> result = new ArrayList<>();

        for (int i = (1<<selection-1); i < Math.pow(2, nodesLlist.size()); i++) { // 遍歷元素>=selection個數的子集合的情況。(注:不是所有的,大於selection,但是是2的倍數的沒有也在了裏面)
            List<NodeTest> list = new ArrayList<>();
            int index = i;  // 爲了計算每個位置上是否有元素
            for (int j = 0; j < nodesLlist.size(); j++) {  //遍歷集合所有數字如果有則添加到集合,沒有則向右位移
                if((index & 1)==1){  //index和1做按位與的操作, 如果等於1說明位置上有元素,如果不等於1說明位置上沒有元素。
                    list.add(nodesLlist.get(j)); //添加到集合中
                }
                index >>= 1;//右移一位,進入下一次循環,用來判斷左邊一位是否是1
            }
            // 去重並且符合selection的子集添加到集合中
            if(list!=null && list.size()>0 && list.stream().map(NodeTest::getId).collect(Collectors.toSet()).size()==list.size()&&list.size()==selection){
                result.add(list); //都添加到大集合中,進行去重
            }
        }


        return result;
    }
}

 

package ceshi.About8;
public class NodeTest {
    public String id;
    public Double value;
    public boolean flag;
    public NodeTest(String id,double value,boolean flag){
        this.id = id;
        this.value = value;
        this.flag = flag;
    }
    public boolean getFlag() {
        return flag;
    }
    public String getId() {
        return id;
    }
    @Override
    public String toString() {
        return "{" +
                "id='" + id + '\'' +
                ", value=" + value +
                ", flag=" + flag +
                '}';
    }

}

總結:短短的幾行代碼是通過自己不斷的優化它才完成的。看着它很開心,知道別人在項目中用它,更開心。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章