我有一个方法会根据值返回一个double。数组中的每个int都在1到6之间,表示连续的掷骰子。
阵列可以是16个大的插槽或小到4个,并且顺序很重要。我不知道如何在java中编写代码来查看总计至少为16的每个排列。在线查找没有任何帮助。
我可怜的代码在下面
public double findMax() {
int[] dice = new int[gameBoard.length];
for(int x : dice) x = 1;
double max = playGame(dice);
/*
int pos = 0;
for(int i = 0; i < dice.length; i++) {
double test = playGame(dice);
if(test > max) test = max;
*/
//This is where I need help, to use the int[] dice for all combinations
//playGame(dice) yields a double
}
答案 0 :(得分:0)
有不同的方法可以做到这一点,但递归对我来说似乎是最好的(比如寻路算法)。看起来这应该是4到16个骰子的排列,总共16或更大(如果数组的长度为16,每个组合可能会产生16或更大的值,所以我不知道是什么目的检查那个长度的排列会产生。)
我可以使用ArrayLists或使用字符串来实现解决方案。我不想在递归函数中使用常规数组,因为它们依赖于固定大小。请务必添加import java.util.ArrayList;
。
无论如何,这是我使用ArrayLists的代码版本。 (注意,我还没有测试过这段代码)
public ArrayList<ArrayList<int>> findPermutations( int size ) {
// To allow the function to work with sizes less than 1
if ( size < 1 )
return new ArrayList<ArrayList<int>>();
ArrayList<ArrayList<int>> permutations = new ArrayList<ArrayList<int>>();
ArrayList<ArrayList<int>> l1 = findPermutations( new ArrayList<int>(), size, 1 );
l1.addAll( findPermutations( new ArrayList<int>(), size, 2 ) );
l1.addAll( findPermutations( new ArrayList<int>(), size, 3 ) );
l1.addAll( findPermutations( new ArrayList<int>(), size, 4 ) );
l1.addAll( findPermutations( new ArrayList<int>(), size, 5 ) );
l1.addAll( findPermutations( new ArrayList<int>(), size, 6 ) );
for( ArrayList<int> a : l1 ) {
if ( computeSum( a ) >= 16 ) {
permutations.add( a );
}
}
return permutations;
}
public ArrayList<ArrayList<int>> findPermutations( ArrayList<int> record, int size, int value ) {
record.add( value );
if ( record.size() >= size ) {
ArrayList<ArrayList<int>> bc = new ArrayList<ArrayList<int>>();
bc.add( record );
return bc;
}
ArrayList<ArrayList<int>> permutations = findPermutations( record.clone(), size, 1 );
permutations.addAll( findPermutations( record.clone(), size, 2 ) );
permutations.addAll( findPermutations( record.clone(), size, 3 ) );
permutations.addAll( findPermutations( record.clone(), size, 4 ) );
permutations.addAll( findPermutations( record.clone(), size, 5 ) );
permutations.addAll( findPermutations( record.clone(), size, 6 ) );
// For variable size array checking
if ( record.size() >= 4 ) {
permutations.add( record );
}
return permutations;
}
public int computeSum( ArrayList<int> list ) {
int total = 0;
for( int x : list ) {
total += x;
}
return total;
}
当你调用这个函数findPermutations( int size )
时,你传递大小(数组长度,基本上是游戏板长度),它将生成所有骰子组合(特定顺序),总共至少16.由于这会返回一个ArrayList,如果要将其转换为double数组,可以使用ArrayList类的toArray()
函数。
ArrayList<ArrayList<int>> permutations = findPermutations( 16 );
ArrayList<int>[] a = ( ArrayList<int>[] ) permutations.toArray();
这将为您提供一个ArrayList
数组要将其转换为数组数组,可以使用循环。
int[][] finalVersion = new int[permutations.size()][16];
for( int i = 0; i < permutations.size(); i++ ) {
finalVersion[i] = ( int[] ) a[i].toArray();
}
希望将它转换回数组数组。
同样,我还没有在代码中测试过这个,所以要小心bug。我现在将对此进行测试,并在不使用ArrayLists的情况下添加另一种执行此计算的方法。
编辑:我稍微改变了一下代码,以便允许 4和大小之间的所有排列(你可以在16中传递)。
答案 1 :(得分:0)
这很简单。初始化一个足够大的数组。递归地填充数组的元素,直到达到16(存储数组)或过冲(丢弃)。每次将数组添加到结果列表时,不要忘记对数组进行深层复制,否则将继续覆盖相同的数组。在代码中:
void createPermutations(int[] prefix, int index, int sum, List<Integer[]> results) {
if (sum == 16) {
results.add(createNewIntegerArray(prefix, index));
} else if (sum < 16) {
for (int i = 1; i <= 6; i++) {
prefix[index] = i;
createPermutations(prefix, index+1, sum+i, results);
}
}
}
Integer[] createNewIntegerArray(int[] array, int length) {
Integer[] result = new Integer[length];
for (int i = 0; i < length; i++) {
result[i] = array[i];
}
return result;
}
您可以将其称为:
createPermutations(new int[16], 0, 0, new ArrayList<Integer[]>());
编辑:如果我误解了您的问题,而您并不关心“超出”目标值(16),则应将==
更改为>=
。
答案 2 :(得分:0)
你可以递归地解决它:
Input: list of size n
Solve(n) = { Sum(n,16) } + Solve(n-1)
with: Solve(4) = { Sum(4,16) }
Sum(n,16) = { find n numbers that sum up to 16 }
然后我们有:
Min(n) = 4
Max(n) = 16
Di = Input-List[i]
Di = 1 or 2 or 3 or 4 or 5 or 6
Sum(n,16) = { D1, D2, .. Dn } where D1 + D2 + .. + Dn = 16
要解决Sum(n,16)
,您可以尝试此算法(写为 Java 代码):
PairList<ArrayList<Byte>,Integer> sum (int n, int sum, ArrayList<Byte> list)
{
if (list.size() == 1)
return new Pair<ArrayList<Byte>,Integer>(list, (int)list.get(0));
PairList<ArrayList<Byte>,Integer> result
= new Pair<ArrayList<Byte>,Integer> ();
for (int i=0; i<n; i++)
{
ArrayList<Byte> t = new ArrayList<Byte>(list);
t.remove(i);
PairList<ArrayList<Byte>,Integer> r = sum(n-1, sum, t);
for (ArrayList<Byte> l : r.getFirstList())
if (r.getSecond(l)+list.get(i) <= sum)
{
l.append(list.get(i));
r.set(l, r.getSecond(l)+list.get(i));
result.append(r);
}
}
return result;
}
然后Solve(n,16)
使用Sum(n,16)
:
Map<Byte, PairList<ArrayList<Byte>,Integer>>
solve (int min_n, int max_n, int sum, ArrayList<Byte> list)
{
Map<Byte, PairList<ArrayList<Byte>,Integer>> solution = null;
solution = new Map<Byte, Pair<ArrayList<Byte>,Integer>> ();
for (int i = min_n, i <= max_n; i++)
solution.put(i, sum(i,sum,list));
for (int i = min_n, i <= max_n; i++)
{
for (int j = 0; j < solution.get(i).count(); j++)
{
// remove all pairs that didn't sum up to total sum
if (solution.get(i).getSecond(j) != sum)
solution.get(i).removePair(j);
}
}
return solution;
}
注意:上面的代码是伪代码