洗牌在英文中叫shuffle,实际应用中就是给定一个数组, 将其中的元素打乱。
这个问题最开始学习js时遇到, 也有一个很好玩的办法:
function shuffle(arr) {
if (!Array.isArray(arr)) {
return arr;
}
return arr.sort((a, b) => {
return Math.random() > 0.5 ? -1 : 1;
});
}
// 可能为: [4, 1, 9, 5, 7, 8, 2, 10, 3, 6]
shuffle(Array.from({length: 10}).map((_, i) => i + 1));
那么如果我们直接来实现shuffle, 可以这样:
假定元素个数为n,
从最后一个元素a[n-1]开始, 在前n个元素中随机找一个和a[n-1]交换(有可能自己和自己交换), 然后再从a[n-2]开始, 在前n-1个元素中随机找一个和a[n-2]交换, 如此反复, 直到第二个元素已经完成交换。
function shuffle2(arr) {
if (!Array.isArray(arr)) {
return arr;
}
let i = arr.length, j = 0, tmp;
while (i > 1) {
j = parseInt(Math.random() * i); // stmt1
--i; // stmt2
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
return arr;
}
// 可能为: [4, 10, 5, 2, 9, 6, 7, 8, 3, 1]
shuffle2(Array.from({length: 10}).map((_, i) => i + 1));
上面的shuffle2计算的结果中, 有可能一个元素shuffle之后还在原来的位置,
只需要将stmt1和stmt2两句代码交换位置即可。
欢迎补充指正!