如何连接二维数组中的列?

时间:2014-03-13 11:45:18

标签: java arrays algorithm combinations

如何连接二维数组中的列?

a b c d
1 3 9 6
4 2 7 1

自动检查列数。

例如:

如果有四列,则应考虑三种组合。

输出应为:

首先采取两种组合:

ab ac ad bc bd cd
13 19 16 39 36 96
42 47 41 27 21 71

然后采取三种组合:

abc abd bcd acd
139 136 396 196
427 421 271 471

我该如何编码?

以下是我试图获得这两种组合的代码。如何更改它以获得上述输出?

for (int i = 0; i < row.size(); i++) {
    for (int j = 0; j < col.size(); j++) {
        for (int k = j + 1; k < col.size(); k++) {
            array1.add(col[j]);
            array2.add(col[k]);
            array.add(array1.get(j) + array2.get(k));
        }
    }
    System.out.println("array");
}

1 个答案:

答案 0 :(得分:2)

我发现这个问题非常有趣,所以我最终花了一些时间。 :)

有几点意见:

  • 对每一行执行相同的组合,因此可以将问题简化为组合一行的列,然后对每一行应用相同的方法。
  • 您似乎并不是在寻找所有排列,而是要查找列与数组中后面的列组合的子集。即你不想要ab和&amp; ba,只是ab
  • 结果应包含2..n-1列的组合(其中n是列数)。即您似乎只需要1列(原始列)或n列(所有列的组合)。

如果根据观察结果将问题分开,找到解决方案要简单得多:

  1. 在一行中查找列的所有组合。这个问题也可以分为两个:

    a)从2..n-1迭代(要合并的列数) - 我为level调用了这个。也许不是最好的名字,但这对我来说很有意义。

    b)查找当前level的所有组合,并将其添加到结果中。

  2. 将其应用于数组中的每一行以生成最终生成的数组。

  3. 如果这些观察结果给了你一些想法,你可能想停止在这里阅读并亲自尝试。自己解决这些问题要比看完成的解决方案更有趣。但是,如果您遇到困难 - 或者您已经解决并想要查看另一个(可能是不同的)解决方案,请提前阅读。

    算法

    第1步:合并一行中的列。

    a)迭代2..n-1的等级。级别表示要组合的列数。

    b)找到组合列的值。

    请注意,第一列是从0..n级别中选择的。第二个来自范围c1 + 1..n-level + 1(其中c1是第一个选定列的索引)。第三个来自范围c2 + 2..n-level + 2。依此类推,直到我们添加了正确数量的列。

    c)将组合列的值添加到结果中。

    第2步:将第1步应用于输入数组中的每一行。

    a)迭代输入数组中的每一行。

    b)将第1步应用于该行。

    c)将结果行添加到输出数组。

    实施

    第1步:RowCombine

    import java.util.ArrayList;
    import java.util.List;
    
    public class RowCombine {
    
        String[] row;
        List<String> result = new ArrayList<String>();
    
        public RowCombine(String[] row) {
            this.row = row;
        }
    
        public String[] combine() {
            if (result.isEmpty()) {
                for (int level = 2; level < row.length; level++) {
                    combine(level, 0, row.length - level, "");
                }
            }
            return result.toArray(new String[result.size()]);
        }
    
        private void combine(int level, int lower, int upper, String value) {
            if (level > 0) {
                for (int c = lower; c <= upper; c++) {
                    combine(level - 1, c + 1, upper + 1, value + row[c]);
                }
            } else {
                result.add(value);
            }
        }
    }
    

    第2步:ArrayCombine

    public class ArrayCombine {
        String[][] input;
        String[][] output;
    
        public ArrayCombine(String[][] input) {
            this.input = input;
        }
    
        public String[][] combineColumns() {
            if (output == null) {
                output = new String[input.length][];
                for (int i = 0; i < input.length; i++) {
                    RowCombine rowCombine = new RowCombine(input[i]);
                    output[i] = rowCombine.combine();
                }
            }
            return output;
        }
    
        public void print() {
            combineColumns();
            for (String[] row : output) {
                for (String value : row) {
                    System.out.print(value + ' ');
                }
                System.out.println();
            }
        }
    }
    

    <强>测试

    运行

    new ArrayCombine(new String[][]{
            { "a", "b", "c", "d"},
            { "1", "3", "9", "6"},
            { "4", "2", "7", "1"},
    }).print();
    

    产生

    ab ac ad bc bd cd abc abd acd bcd 
    13 19 16 39 36 96 139 136 196 396 
    42 47 41 27 21 71 427 421 471 271 
    

    它也适用于更高的尺寸,例如:

    new ArrayCombine(new String[][]{
            { "a", "b", "c", "d", "e"},
            { "1", "3", "9", "6", "5"},
            { "4", "2", "7", "1", "1"},
    }).print();
    

    产生

    ab ac ad ae bc bd be cd ce de abc abd abe acd ace ade bcd bce bde cde abcd abce abde acde bcde 
    13 19 16 15 39 36 35 96 95 65 139 136 135 196 195 165 396 395 365 965 1396 1395 1365 1965 3965 
    42 47 41 41 27 21 21 71 71 11 427 421 421 471 471 411 271 271 211 711 4271 4271 4211 4711 2711