var testArray = [0, 1, 2, 3, 4, 5, 6]
如果我有这个数组并想打乱它,我知道使用Fisher-Yates Shuffle,但是如何以更有组织的方式对它进行洗牌?如何在JS中专门洗牌数组?
一样,我将如何洗牌,但也保证0
绝不会出现在洗牌后的数组中的第一点,1
绝不会在阵列的第二位,2
绝不会在第三位等等等等。
var testArray = [0, 1, 2, 3, 4, 5, 6]
如果我有这个数组并想打乱它,我知道使用Fisher-Yates Shuffle,但是如何以更有组织的方式对它进行洗牌?如何在JS中专门洗牌数组?
一样,我将如何洗牌,但也保证0
绝不会出现在洗牌后的数组中的第一点,1
绝不会在阵列的第二位,2
绝不会在第三位等等等等。
考虑使用Sattolo算法,描述为here。
它与Fisher-Yates基本相同,只是有一个小小的变化导致阵列中的元素无法保留在他们自己的位置,这似乎就是您所描述的。
var finalArray = [];
function getUniqueNumber() {
var uniqueNumber = Math.floor(Math.random() * 6) + 0;
var doesExist = finalArray.indexOf(uniqueNumber) === -1;
if (!doesExist) {
return getUniqueNumber();
} else {
return uniqueNumber;
}
}
function generateTestArray() {
for (var i = 0; i < 6; i++) {
finalArray.push(getUniqueNumber());
}
console.log(finalArray);
}
这将始终生成一个唯一混淆索引的测试数组。
/** fisher yates as seen on wikipedia
* for i from n−1 downto 1 do
* j ← random integer such that 0 ≤ j ≤ i
* exchange a[j] and a[i]
*/
/** modified fisher yates as described
* for i from n−1 downto 1 do
* j ← random integer such that 0 ≤ j ≤ i, j != i, a[j] != i, a[i] != j
* exchange a[j] and a[i] (where a[j] != i)
*/
let modifiedFYShuffle = (array) => {
let swap = (i, j) => {
let tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
for (let i = array.length - 1; i >= 0; --i) {
let j = i;
while (j === i || array[j] === i || array[i] === j) {
j = Math.floor(Math.random() * array.length);
}
swap(i, j)
}
}
let makeArray =() => {
let array = [];
for (let i = 0; i < 10; ++i) {
array[i] = i;
}
return array;
}
for (let i = 0; i < 10; ++i) {
let array = makeArray();
modifiedFYShuffle(array);
console.log(array)
}
为什么不在你所描述的数组的切片上使用fisher yates?然后重新加入他们? – Catalyst