需求:从长度为N的数组中,先剔除掉X个数,再从剩下的数里随机取M个数。
假设N=1000,X为所有10的倍数(100个),M=10。
方法1
最简单也是最快接的的,用while去不断取数组下标,如果未添加过则添加,直到取到M个为止。
JS代码:
const fs = require('fs');
let outStr = "";
let resultArr = [];
let runTimes = [];
let arr = []; // 初始数组
let excludeArr = []; // 需要剔除的数字
for (let i = 0; i < 1000; i++) {
arr.push(i);
resultArr.push(0);
if (i % 10 === 0) {
excludeArr.push(i);
}
}
// 剔除过的数组
let exArr = arr.filter(v => {
return excludeArr.indexOf(v) === -1;
})
outStr += `需要剔除的数字 excludeArr 长度为${
excludeArr.length}\n`;
outStr += `剔除过的数组 exArr 长度为${
exArr.length}\n`;
for (let count = 0; count < 100000; count++) {
let randList = [];
let needNum = 10; // 需要几个随机数
let run = 0;
while (randList.length < needNum) {
let randIdx = Math.floor(Math.random() * exArr.length);
if (randList.indexOf(randIdx) === -1) {
randList.push(randIdx);
}
run++;
}
for (let i = 0; i < randList.length; i++) {
resultArr[exArr[randList[i]]]++;
}
runTimes.push(run);
}
//计算平均执行次数
let sum = 0;
for (let i = 0; i < runTimes.length; i++) {
sum += runTimes[i];
}
sum = sum / runTimes.length;
outStr += `平均执行${
sum}次找齐随机数组\n`;
resultArr.forEach((v