2D阵列的元素组合数量是可能的吗?

时间:2014-04-06 10:29:47

标签: java arrays

我有5x5元素表。让我们说该表中的每一行都是一个罐子。行中的每个元素都是jar中的不同颜色的球。 我们从第一个罐子拿一个球,从第二个罐子拿一个球,从第三个罐子拿一个球......依此类推到第五个罐子。 我们有5个球颜色组合......然后我们把球放回相关的罐子里。 问题:可能有多少组合变体? 回答n ^ n,其中n是表大小!

问题是,我永远不知道大桌子有多大,尽管它总是对称的(n×n)元素。我想编写UNIVERSAL方法,它将返回所有可能的颜色组合。

对于表5x5元素,它看起来像这样:

private int combinations = 0;
private char table[][] = { {'A','B','C','D','E'},
                           {'F','G','H','I','J'}, 
                           {'K','L','M','N','O'},
                           {'P','Q','R','S','T'},
                           {'U','V','X','Y','Z'}};  

public Prog() {     

    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            for (int k= 0; k < 5; k++) {
                for (int l = 0; l < 5; l++) {
                    for (int m = 0; m < 5; m++) {

                        System.out.println(table[0][i] +" " + table[1][j]+ " " + table[2][k]+ " " + table[3][l]+ " " + table[4][m]);                            
                        combinations++;
                    }
                    System.out.println("--------------");
                }                   
            }
        }           
    }       
    System.out.println("Total combination is : " + combinations);   
}

...但上面的代码仅适用于5x5表。如果我得到4x4或3x3,我需要修改所有的for循环才能正常工作...... 有人请帮我写一个方法,根据表格大小修改自己并返回正确的组合吗?

谢谢!

6 个答案:

答案 0 :(得分:3)

这个问题的递归解决方案:

import java.math.BigInteger;
import java.util.Arrays;

/**
 * Created for http://stackoverflow.com/q/22892808/1266906
 */
public class Combinations {

    public static BigInteger printCombinationsRecursively(char[][] table) {
        return printCombinationsRecursively(table, new char[table.length], 0);
    }

    public static BigInteger printCombinationsRecursively(char[][] table, char[] selection, int currentRow) {
        if(currentRow >= table.length) {
            System.out.println(Arrays.toString(selection));
            return BigInteger.ONE;
        }
        BigInteger count = BigInteger.ZERO;
        for (char c : table[currentRow]) {
            selection[currentRow] = c;
            count = count.add(printCombinationsRecursively(table, selection, currentRow + 1));
        }
        return count;
    }

    public static void main(String[] args) {
        char[][] table = new char[][] {
                new char[] {'A', 'B', 'C', 'D'},
                new char[] {'E', 'F', 'G', 'H'},
                new char[] {'I', 'J', 'K', 'L'},
                new char[] {'M', 'N', 'O', 'P'}
        };
        final BigInteger combinations = printCombinationsRecursively(table);
        System.out.println(combinations + " combinations");
    }
}

答案 1 :(得分:1)

具有相同输出的5x5阵列的迭代版本:

void Prog() {
    int baseN = table.length;
    int maxDigits = table[0].length;
    int max = (int) Math.pow(baseN, maxDigits);
    // each iteration of this loop is another unique permutation
    for (int i = 0; i < max; i++) {
        int[] digits = new int[maxDigits];
        int value = i;
        int place = digits.length - 1;
        while (value > 0) {
            int thisdigit = value % baseN;
            value /= baseN;
            digits[place--] = thisdigit;
        }

        int tableIdx = 0;
        for (int digitIdx = 0; digitIdx < digits.length; digitIdx++) {
            int digit = digits[digitIdx];
            System.out.print(table[tableIdx][digit] + " ");
            tableIdx++;
        }
        System.out.println();
        combinations++;
        if (i % maxDigits == maxDigits - 1)
            System.out.println("--------------");
    }
    System.out.println("Total combination is : " + combinations);
}

根据我的回答https://stackoverflow.com/a/9315076/360211,我将此视为5位数,基数为5。

请注意,因为我对int使用了max,而您将其用于combinations,因此限制为9x9数组,因为10^10 > Integer.MAX_VALUElong会给你15x15,但这需要才能运行!!!

答案 2 :(得分:0)

使用数组的。length字段来确定表的大小:

for (int i = 0; i < table.length; i++) {
    (..)

此字段始终包含正确的数组大小。

答案 3 :(得分:0)

我认为这些方法不是非常优化,这是从NxN表中获取排列的一般方法。这是在Javascript中但是给出了方法的概念

var table = [ ['A','B','C','D','E'],
              ['F','G','H','I','J'],
              ['K','L','M','N','O'],
              ['P','Q','R','S','T'],
              ['U','V','X','Y','Z']];


function perm(l) {
    var n = Math.pow(l.length,l.length);
    for(var i=0; i < n; i++) {
        var s = '';
        var m = i;
        for(var k=0 ; k < l.length; k++) {
            var p = m % 5;
            s += l[k][p];
            m = ~~(m / 5);
        }
        console.log(s);
    }
}

perm(table);

答案 4 :(得分:0)

这是一个易读且易于解决的解决方案:让我们将其视为具有n位数的n基数。

假设您有一个存储数字(可能的颜色)的数组。在这种情况下,您可以通过这种方式生成排列(而不是组合)(代码未经测试):

public int[] nextPermutation(int[] input, int base) {
    if (input == null) {
        int[] returnValue = new int[base];
    }

    int modulo = 1;
    for (int digitIndex = 0; (modulo > 0) && (digitIndex < input.length); digitIndex++) {
        input[digitIndex] = (input[digitIndex] + 1) % base;
        modulo = ((input[digitIndex] > 0) ? (1) : (0));
    }

    return ((modulo == 0) ? (input) : (null));
}

public int[] getColorByPermutation(int[] permutation, int[] colors) {
    int[] result = new int[permutation.length];
    for (int permutationIndex = 0; permutationIndex < permutation.length; permutation++) {
        result = colors[permutation[permutationIndex]];
    }
}

public void generatePermutations(int base, int[] colors) {
    int permutation = nextPermutation(null, base);
    while (permutation != null) {
        int[] currentColors = getColorByPermutation(permutation, colors);
        //Do whatever you need with the colors
        permutation = nextPermutation(permutation, base);
    }
}

答案 5 :(得分:0)

不幸的是我只知道Python,但我认为以下两种解决方案可以满足您的需求。

<强>递归

class Permutations:
    def __init__(self, matrix):
        self.matrix = matrix
        self.n = len(matrix)
        self.permutations(self.n)
        print('There are {} permutations!'.format(self.n**self.n))

    def permutations(self, count, sequence=[]):
        if count == 0:
            chars = [self.matrix[i][sequence[i]] for i in range(self.n)]
            print(' '.join(chars))
            return None
        for x in range(self.n):
            self.permutations(count-1, sequence+[x])
        if count == 1:
            print('---------------')

<强>迭代

def decimal_to_base_n(decimal, base):
    digits = []
    while decimal:
        digit = decimal%base
        digits.append(digit)
        decimal //= base
    digits += [0]*(base-len(digits))
    return digits[::-1]

def permutations(matrix):
    n = len(matrix)
    for i in range(n**n):
        sequence = decimal_to_base_n(i, n)
        chars = [matrix[j][sequence[j]] for j in range(n)]
        print(' '.join(chars))
        if i%n == n-1:
            print('---------------')
    print('There are {} permutations!'.format(n**n))