我有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循环才能正常工作...... 有人请帮我写一个方法,根据表格大小修改自己并返回正确的组合吗?
谢谢!
答案 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_VALUE
。 long
会给你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))