多層陣列笛卡爾積
阿新 • • 發佈:2021-01-06
技術標籤:java
遇到一個問題,要求不定長度多維陣列的笛卡爾積集合,找了和很多資料都是二維的,然後我在二維基礎上,寫了個多維的
利用雙層陣列笛卡爾積方法,處理多層陣列的笛卡爾積,
該例子以long 型別陣列為例
@org.junit.Test public void testDecartes() { // List<List<String>> listLevel2 = Lists.newArrayList(Lists.newArrayList("a","b","c"),Lists.newArrayList("d","e","f")); // List<List<String>> result = CollectionUtil.decartes(listLevel2); // logger.info("result:{}",result); List<List<String>> listLevel2 = new ArrayList<>(); listLevel2.add(Lists.newArrayList("1","2","3")); listLevel2.add(Lists.newArrayList("4","5","6")); listLevel2.add(Lists.newArrayList("7","8","9")); List<String> resultFinal = listLevel2.get(0); for(int i =1 ;i < listLevel2.size();i++){ List<List<String>> currResult = CollectionUtil.decartes(Lists.newArrayList(resultFinal,listLevel2.get(i))); //currResult 轉換成逗號隔開一維list ,resultFinal 值更新 resultFinal.clear(); for(List<String> one : currResult){ resultFinal.add(String.join(",",one)); } } //List<String> 轉 List<List<Long>> List<List<Long>> finalResultLong = new ArrayList<>(); resultFinal.forEach( one ->{ finalResultLong.add( Arrays.stream(one.split(",")).map(oneStr->{ return Long.parseLong(oneStr); }).collect(Collectors.toList()) ); }); logger.info("finalResultLong:{}",finalResultLong); }
CollectionUtils:
// Copyright 2016 Leyantech Ltd. All Rights Reserved. package com.leyantech.eci.pm.util; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author lxc, {@literal <[email protected]>} * @date 2020-06-10. */ public class CollectionUtil { /** * Check whether a given list is null or empty */ public static boolean isNullOrEmpty(Collection<? extends Object> list) { return list == null || list.isEmpty(); } /** * 計算笛卡兒積 * * @param crossArgs a {@link java.util.List} object. * @param <T> a T object. * @return a {@link java.util.List} object. */ public static <T> List<List<T>> decartes(List<List<T>> crossArgs) { // 計算出笛卡爾積行數 int rows = crossArgs.size() > 0 ? 1 : 0; for (List<T> data : crossArgs) { rows *= data.size(); } // 笛卡爾積索引記錄 int[] record = new int[crossArgs.size()]; List<List<T>> results = new ArrayList<List<T>>(); // 產生笛卡爾積 for (int i = 0; i < rows; i++) { List<T> row = new ArrayList<T>(); // 生成笛卡爾積的每組資料 for (int index = 0; index < record.length; index++) { row.add(crossArgs.get(index).get(record[index])); } results.add(row); crossRecord(crossArgs, record, crossArgs.size() - 1); } return results; } /** * @param record * @param level */ private static <T> void crossRecord(List<List<T>> sourceArgs, int[] record, int level) { record[level] = record[level] + 1; if (record[level] >= sourceArgs.get(level).size() && level > 0) { record[level] = 0; crossRecord(sourceArgs, record, level - 1); } } }