【问题标题】:How do I generate combinations of two arrays?如何生成两个数组的组合?
【发布时间】:2020-12-06 15:23:44
【问题描述】:

给定两个数组,其中数组一包含变量,数组二包含变量的值,我想获取这两个数组的所有可能组合,例如:

String[] arr = {"E", "A", "C"};
String[] val = {"true", "false"};

数组arr可以容纳尽可能多的变量,val也可以。

期望的输出:

E true A true C true
E true A true C false
E true A false C true
E true A false C false

E false A true C true
E false A true C false
E false A false C true
E false A false C false

我尝试了递归方法:

import java.util.*;

class Main {
    public static void main(String[] args) {
        String[] arr = {"E", "A", "C"};
        String[] val = {"true", "false"};
        printAll(arr, val, 0);
    }

    public static void printAll(String[] x, String[] y, int index) {
        if (x.length == 0) {
            return;
        }
        for (String d : x) {
            for (String val : y) {
                System.out.print(d + " " + val + " ");
                String[] arr2 = Arrays.copyOfRange(x, index + 1, x.length);
                printAll(arr2, y, index);
            }
        }
        System.out.println();
    }
}

但我得到的输出是:

E true A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

E false A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

A true A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

A false A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

C true A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

C false A true C true C false 
A false C true C false 
C true C true C false 
C false C true C false 

我希望能够将每个正确的行保存为 ArrayList 中的一个元素,但首先我想弄清楚如何正确打印每一行。


编辑:第二个数组不是常量,每个变量之间都不同:

String[] arr = {"E", "A", "C"};
String[] valE = {"true", "false"};
String[] valA = {"true", "false"};
String[] valB = {"set", "noset", "maybe"};

显然这在递归中不起作用,因为我需要将每个数组与变量数组一起发送,我通过创建一个包含其特定值的 Variables 对象来实现这一点,因此循环将是:

for (String d : x) {
    for (String val : d.getValues()) {...}
}

这与主要问题无关,我只是将问题简化为每个变量都有两个可能值的简单情况。

【问题讨论】:

    标签: java arrays combinations permutation


    【解决方案1】:

    您可以使用map 和reduce 方法生成可能组合的二维数组:

    String[] array = {"E", "A", "C"};
    String[] values = {"true", "false"};
    
    String[][] combinations = Arrays.stream(array)
            // represent each string as a 2d array of possible combinations
            .map(str -> Arrays.stream(values).map(bool -> new String[]{str, bool})
                    // stream of 2d arrays
                    .toArray(String[][]::new))
            // intermediate output
            .peek(comb -> System.out.println(Arrays.deepToString(comb)))
            // reduce stream of 2d arrays to a single 2d array
            .reduce((arr1, arr2) -> Arrays.stream(arr1)
                    // combinations of inner arrays
                    .flatMap(inner1 -> Arrays.stream(arr2)
                            // merge two inner arrays into one
                            .map(inner2 -> Stream.of(inner1, inner2)
                                    .flatMap(Arrays::stream)
                                    .toArray(String[]::new)))
                    // array of combinations
                    .toArray(String[][]::new))
            // otherwise an empty 2d array
            .orElse(new String[0][]);
    
    // final output
    Arrays.stream(combinations).map(Arrays::toString).forEach(System.out::println);
    

    中间输出:

    [[E, true], [E, false]]
    [[A, true], [A, false]]
    [[C, true], [C, false]]
    

    最终输出:

    [E, true, A, true, C, true]
    [E, true, A, true, C, false]
    [E, true, A, false, C, true]
    [E, true, A, false, C, false]
    [E, false, A, true, C, true]
    [E, false, A, true, C, false]
    [E, false, A, false, C, true]
    [E, false, A, false, C, false]
    

    另见:Outputting permutations of ArrayList using recursion

    【讨论】:

      【解决方案2】:

      您可以迭代地使用streams 生成两个数组的所有可能组合,如下所示:

      String[] arr = {"E", "A", "C"};
      String[] val = {"true", "false"};
      
      // an array of possible combinations
      String[] comb = Arrays.stream(arr)
              .map(e -> Arrays.stream(val)
                      // append each substring
                      // with possible combinations
                      .map(v -> e + " " + v + " ")
                      // return Stream<String[]>
                      .toArray(String[]::new))
              // reduce stream of arrays to a single array
              // by sequentially multiplying array pairs
              .reduce((arr1, arr2) -> Arrays.stream(arr1)
                      .flatMap(str1 -> Arrays.stream(arr2)
                              .map(str2 -> str1 + str2))
                      .toArray(String[]::new))
              .orElse(null);
      
      // output
      Arrays.stream(comb).forEach(System.out::println);
      
      E true A true C true 
      E true A true C false 
      E true A false C true 
      E true A false C false 
      E false A true C true 
      E false A true C false 
      E false A false C true 
      E false A false C false 
      

      另见:Generate all possible string combinations by replacing the hidden “#” number sign

      【讨论】:

        猜你喜欢
        • 2015-04-21
        • 2018-03-01
        • 1970-01-01
        • 2016-07-20
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-07
        相关资源
        最近更新 更多