问题
这是一道大题目,把考点拆成了4个小项;需要侯选人用递归算法实现(限制15行代码以内实现;限制时间10分钟内完成)
- 生成一个长度为5的空数组arr。
- 生成一个(2-32)之间的随机整数rand。
- 把随机数rand插入到数组arr内,如果数组arr内已存在与rand相同的数字,则重新生成随机数rand并插入到arr内[需要使用递归实现,不能使用for/while等循环]
- 最终输出一个长度为5,且内容不重复的数组arr。
俺的实现方法
function randomNumber(arr){ var value = Math.floor(Math.random()*31+2); if(~arr.findIndex(item=>item==value))return randomNumber(arr); return value; } function nArr(length,arr){ var arr = typeof arr== 'undefined'?new Array(length):arr; var index = arr.findIndex(item=>item==undefined); if(!~index) return arr arr[index]=randomNumber(arr); return nArr(length,arr); }
错误学习
Math.floor(Math.random()*31+2); 这样的写法是不严谨的,俺学习到了 (●’◡’●)
取范围区间值应该这样写:
Math.floor(Math.random() * (max - min + 1)) + min;
原因如下:
// 在 2 - 5 区间内生成随机数 var min = 2, max = 5; var result = Math.max(min, Math.ceil(Math.random() * max)); // 参数一 p1 恒等于2 // 参数二 p2 在 [0, 5] 之间等概取值 // 可能性见下 // p1 2 2 2 2 2 2 // p2 0 1 2 3 4 5 // result 2 2 2 3 4 5
可见 result 取到 2 的概率大于 3/4/5。
别人的实现方式
俺看了一个比较优雅的代码,代码实现如下:
// 6 行写完 function buildArray(arr, length, min, max) { var num = Math.floor(Math.random() * (max - min + 1)) + min; if (!arr.includes(num)) { arr.push(num); } return arr.length === length ? arr : buildArray(arr, length, min, max); } var result = buildArray([], 5, 2, 32); console.table(result);