1

我有一个Map<Integer, List<Float>>代表有一些分数的位置,我想生成每个位置的所有可能的分数组合(基本上是原始地图中每个列表的叉积)到List<List<Float>>. 所以假设我有以下地图:

{ 1 => [0.1f, 0.2f], 2 => [0.3f, 0.4f] }

我会得到以下浮动列表列表:

[[0.1f, 0.3f], [0.1f, 0.4f], [0.2f, 0.3f], [0.2f, 0.4f]]

我很确定我必须使用递归,只是不知道如何继续它..

4

3 回答 3

1

任何时候你有一个递归算法来编码,你都需要一个归纳定义来帮助设计它。

基本情况:{} ↦ []
归纳步骤: M ↦ L ⇒ ( M ∪ { n ↦ S } ) ↦ L × S

对于 S 中的每个元素,将其添加到 L 中每个列表的末尾,并将结果列表添加到输出中。

List<List<Float>> llfNext = new LinkedList<List<Float>>();
for (float f : entEach.getValue())
    for (List<Float> lfEach : llfInductive)
        llfNext.add(copyAndAddToEnd(lfEach, f));
return llfNext;

从这里开始应该很容易,然后你可以使它成为非递归的并减少一些复制。

于 2012-05-17T18:17:05.683 回答
1

使用Java 9,您可以将列表映射的所有组合生成为映射列表如下所示。

在线尝试!

Map<Integer, List<Float>> mapOfLists = new LinkedHashMap<>();
mapOfLists.put(1, List.of(0.1f, 0.2f));
mapOfLists.put(2, List.of(0.3f, 0.4f));
mapOfLists.put(3, List.of(0.5f, 0.6f));
List<Map<Integer, Float>> listOfMaps = mapOfLists.entrySet().stream()
        // Stream<List<Map<Integer,Float>>>
        .map(entry -> entry.getValue().stream()
                // represent list elements as Map<Integer,Float>
                .map(element -> Map.of(entry.getKey(), element))
                // collect a list of maps
                .collect(Collectors.toList()))
        // intermediate output
        //[{1=0.1}, {1=0.2}]
        //[{2=0.3}, {2=0.4}]
        //[{3=0.5}, {3=0.6}]
        .peek(System.out::println)
        // reduce a stream of lists to a single list
        // by sequentially multiplying the list pairs
        .reduce((list1, list2) -> list1.stream()
                // combinations of elements,
                // i.e. maps, from two lists
                .flatMap(map1 -> list2.stream()
                        .map(map2 -> {
                            // join entries of two maps
                            Map<Integer, Float> map =
                                    new LinkedHashMap<>();
                            map.putAll(map1);
                            map.putAll(map2);
                            return map;
                        }))
                // collect into a single list
                .collect(Collectors.toList()))
        .orElse(null);
// output a list of map values
listOfMaps.stream().map(Map::values).forEach(System.out::println);
//[0.1, 0.3, 0.5]
//[0.1, 0.3, 0.6]
//[0.1, 0.4, 0.5]
//[0.1, 0.4, 0.6]
//[0.2, 0.3, 0.5]
//[0.2, 0.3, 0.6]
//[0.2, 0.4, 0.5]
//[0.2, 0.4, 0.6]

另请参阅:将列表映射转换为映射列表

于 2021-03-19T20:42:23.443 回答
0
List<List<Float>> finalList = new ArrayList<List<Float>>();
int pointsCounter = 0;
for (Integer key : map.keys()) {
    List<Float> scoresList = map.get(key);
    boolean firstValue = true;
    for (Float score : scoresList) {
        if (firstValue) {
            finalList.add(new ArrayList<Float>());
            firstValue = false;
        }
        finalList.get(pointsCounter).add(score);
    }
    pointsCounter++;
}
于 2012-05-17T18:25:04.200 回答