假設你有一個要求,即所有可能的結果是等可能的,那麼唯一的簡單的方法將是窮舉創建所有組合,然後從該隨機選擇。所有組合都是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;
}
你試過了什麼? – Alex
你的方法是錯誤的 - 它可能需要很多重試才能通過隨機混洗列表來達到所需的狀態。你應該想出一個算法,強制所需的洗牌,例如,通過混洗奇數和偶數分開,然後合併它們。 – dasblinkenlight
@Alex:我嘗試只是說明幾個if語句等: 如果(rng.get(ⅰ).equals(0)&& rng.get第(i + 1).equals(1)){Collections.shuffle(RNG) ;} – Joilin