首先,我不是母语为英语的人,所以请原谅我一些错误和错误。
我想要洗牌一个ArrayList(没有问题),但是在洗牌之后,列表必须满足某些条件。 我的第一种方法是创建if语句并在每次真实时进行随机播放。但是有很多条件,我不知道如何正确地链接它们。
实施例: 我有一个带有这些整数的ArrayList:
0, 1, 2, 3, 4, 5, 6
改组后的条件:
ArrayList中的每个元素只应列出一次,这就是为什么我认为改组是创建新List的最简单方法。
我错了吗?有没有更简单的方法?我对编程很新... 提前感谢您的任何答案或建议。
编辑:以下是所有条件:
嗯,我认为就是这样。
如果我想创建多个if语句,我的主要问题是找出有效链接它们的正确方法(以便考虑每个if语句)。
答案 0 :(得分:1)
洗牌方法并不好,原因有两个:
我建议另一个解决方案:
canFollow
,如果给定的数字可以扩展我们到目前为止的结果列表,则返回true。 (你给出的规则允许使用两个数字的更简单的函数,但对于更复杂的条件,如5 can be followed by 8 only when not preceded by 6
,更通用的函数将起作用。)在伪代码中:
List<Int> brute(List<Int> result, List <Int> given) {
if (given is empty) return result;
foreach i in given
if i can follow result
r = brute(result + i, given - i)
if r != null return r
return null
}
solution = brute([], [1,2,3,4,5,6])
(注意结果+ i是结果的缩写,其中i附加并给定 - 我没有给出i,但请确保你构造它而不会破坏原始结果并给出。)
如果您需要所有解决方案,可以通过向一些空白的列表添加有效结果来轻松更改。
答案 1 :(得分:0)
假设您要求所有可能的结果同样可能,那么唯一简单的方法就是蛮力创建所有组合,然后从中随机选择。所有组合都是7! == 7*6*5*4*3*2*1 == 5040
组合,实际上并不多。对于更大的数字,我不会推荐这种方法。
List<int[]> valid = new ArrayList<>(5040);
recursiveBuild(valid, new int[] {}, new int[] { 0,1,2,3,4,5,6));
recursiveBuild是:
void recursiveBuild(List<int[]> valid, int[] soFar, int[] remaining) {
if (remaining.length == 0) {
// Check the whole thing is valid - can maybe skip this check
// if the character-by-character check covers everything
if (isValid(soFar)) {
valid.add(soFar);
}
} else {
for (int i=0;i<remaining.length;i++) {
int[] newSoFar = new int[soFar.length+1];
for (int j=0;j<soFar.length;j++) {
newSoFar[j]=soFar[j];
}
newSoFar[newSoFar.length-1]=remaining[i];
int[] newRemaining = new int[remaining.length-1];
for (int j=0;j<newRemaining.length;j++) {
if (j>=i) {
newRemaining = remaining[j+1];
} else {
newRemaining = remaining[j];
}
}
// Only continue if the new character added is valid
if (isValid(newSoFar, newSoFar.length-1)
recursiveBuild(valid, newSoFar, newReamining);
}
}
}
为了解决您列出的实际问题,我将在策略模式上使用一个变体,将每个规则定义为自己的对象(在Java 8闭包中,这将使这一点更加冗长):
interface CheckCondition {
boolean passesCondition(int index, int[] arr);
}
CheckCondition[] conditions = new CheckCondition[] {
new CheckCondition() {
@override
public boolean passesCondition(int index, int[] arr) {
// The list has to start with an even number
return index!=0 || arr[index]%2==0;
}
},
new CheckCondition() {
@override
public boolean passesCondition(int index, int[] arr) {
// an even number can't follow an even number, unless it's 6.
return index==0 || arr[index]==6 || arr[index]%2==1 || arr[index-1]%2==1;
}
},
new CheckCondition() {
@override
public boolean passesCondition(int index, int[] arr) {
// a number can't be followed by the next closest one unless its 6
return index==0 || arr[index]!=arr[index-1]-1 || arr[index]==6;
}
},
};
现在使用这些规则来检查有效性:
boolean isValid(int[] arr, int index) {
for (CheckCondition c: conditions)
if (!c.passesCondition(arr.length-1, arr)
return false;
return true;
}
boolean isValid(int[] arr) {
for (int i=0;i<arr.length;i++) {
if (!isValid(arr, i);
return false;
}
return true;
}