例如,我想生成5 唯一之間的數字10 & 10.結果應該是從1到10的5個數字(例如2 3 4 8 10)。你如何隨機生成X數量的數字,在JavaScript和Y和Z範圍之間?
回答
- 填補了數組與你的價值觀的範圍
- 洗牌陣列
- 挑頭5個元素
如果範圍是非常大的,並且希望值的數目是非常小(例如1 ... 1000000範圍內的5個不同值),那麼您可以嘗試在範圍內生成隨機數並丟棄(不太可能)重複,直到您有5個。「繼續嘗試」方法的問題是有一個小小的機會,你可以花費大量的時間用一串隨機值gi給你很多重複的東西。對於大範圍的價值來說,這是不太可能的,除非軟件給創傷患者提供氧氣或者其他東西,否則它可能值得冒險。
另一種方法是生成隨機數字,並只將它們添加到 返回的數組中,如果它沒有包含它們。
function randomRange(from, to, leng){
var tem, A= [], L= 0, i= 0;
randomRangeLoop:
while(L< leng){
tem= Math.floor(Math.random()*to)+from;
i= 0;
while(i<L){
if(A[i++]=== tem) continue randomRangeLoop;
}
A[L++]= tem;
}
return A;
}
警報(randomRange(1,10,5))
/*返回的值:(陣列) 8,6,1,3,5 */
function generateNumbers(resultCount, from, to) {
var result = []; // holds the final result
var isAlreadyPicked = []; // quick lookup for the picked numbers
// holds substitutes for when we pick a number that has been picked before
var substitutes = [];
for (var i = 0; i < resultCount; i++) {
// pick a random number
var number = Math.floor(Math.random() * (to - from)) + from;
if(isAlreadyPicked[number]) {
// pick a number from the ones we skipped at the end of the range.
var j = Math.floor(Math.random() * substitutes.length);
number = substitutes[j];
substitutes.splice(j, 1);
}
// Save the number and mark it as being picked.
result.push(number);
isAlreadyPicked[number] = true;
// decrease the range. (Because there is 1 less number to choose from)
to -= 1;
if(!isAlreadyPicked[to]) {
// Save a substitute for when we pick the same number in a next iteration.
substitutes.push(to);
}
}
return result;
}
它通過每次迭代減少範圍的頂部來工作。如果在前一次迭代中選取的數字已經存在於結果中,只需將其更改爲我們排除在範圍之外的其中一個頂部數字(那裏將始終只有1個未被選中的數字)。這也是一個真正的隨機數,因爲它實際上存在於前面一次迭代中挑選的數字中。
在我看來這是最好的 解決方案,因爲:
它不通過分配所有的數字數組 和洗牌數組分配大量內存 。
它只是X迭代所以把它掛 到這個呼吸機:)
這是真正的隨機,我以前 答案在我加1,如果數量 已經挑不。因爲 之前 迭代中挑選的編號 之後的編號比其他編號獲得挑選的機會多兩倍。
編輯1:我是在大量案件測試此算法和我犯了一個小錯誤。有一個邊緣情況,有時這些數字不是唯一的。發生這種情況時,該範圍內的其中一位頂級號碼已被選中。我更新了我的代碼。
編輯2:如果你有興趣:這裏是我用來測試這個代碼:
function test(cases, size) {
var errors = 0;
for (var i = 0; i < cases; i++) {
var start = Math.floor(Math.random() * size);
var end = start + Math.floor(Math.random() * size);
var count = Math.floor(Math.random() * (end - start));
var nrs = generateNumbers(count, start, end);
console.log('testing', start, end, count, nrs);
test:
for (var j = 0; j < count; j++) {
var testedNumber = nrs[j];
if(testedNumber < start || testedNumber >= end) {
console.error('out of range', testedNumber);
errors += 1;
break test;
}
for (var k = 0; k < count; k++) {
if(j !== k && nrs[k] === testedNumber) {
console.error('picked twice', testedNumber);
errors += 1;
break test;
}
}
}
}
console.log('all tests finished | errors:', errors)
}
test(1000, 20);
編輯3:尖尖建議使用更快的算法看,如果一個號碼是獨特。我用他/她的建議更新了樣本。謝謝Pointy!
編輯4:通過刪除內部循環並將其替換爲替代數組,使算法更高效一些。有趣的是,這個算法實際上可以用作前面答案中的混洗算法:)
這個問題讓我很感興趣。我以前需要這樣的算法。這實際上是我第一次找到滿足我的解決方案。我對這個主題做了一些研究,這似乎是Fisher-Yates shuffle算法的一個變種。
編輯5:改變算法,從替代品中選擇一個隨機數而不是第一個。
- 1. x和y之間的隨機數,不包括數字範圍
- 2. 在X和Y之間生成一個隨機數,排除某些數字
- 3. 隨機數字生成器Javascript - 範圍
- 4. 生成範圍之間的隨機數,包括在javascript
- 5. R:如果另一個向量中的值在x和y之間,則範圍之間的隨機數
- 6. 如何隨機生成-0.5和0.5範圍內的數字?
- 7. 獲取範圍(隨機整數X,Y]
- 8. 如何在'X'和'O'之間隨機生成一個字符?
- 9. 生成隨機的X和Y一盒
- 10. 如果數字在X和Y之間
- 11. 在x和y之間但不在a和b之間生成隨機數的最佳方法
- 12. 在隨機字節的給定範圍內生成隨機數
- 13. sh在範圍之間的隨機數
- 14. 如何在生成文件的範圍內生成隨機數?
- 15. 生成多個之間的隨機數範圍
- 16. 生成兩個範圍之間的隨機整數
- 17. 如何生成[0,1]和3分數之間的隨機數
- 18. 如何在C中生成-1和1之間的隨機數?
- 19. 如何在用戶範圍內生成隨機數字?
- 20. Javascript:生成範圍內的隨機數字,避免前兩個
- 21. 的javascript:從範圍生成2個隨機,但不同數字
- 22. 生成範圍內的隨機數
- 23. 生成一個隨機數的範圍
- 24. 如何在一定量之間生成隨機數量的數字?
- 25. 使用Javascript中的隨機x和y座標生成矩陣
- 26. 如何在0和2pi之間生成隨機數?
- 27. .NET的 - 如何生成一定範圍內的隨機數字?
- 28. 如何在每個數字位於數字範圍內生成隨機數字?
- 29. 如何獲得浮動範圍之間的隨機數字?
- 30. x + y-z -1和1之間
非常整齊,我每次都在考慮生成一個隨機值,並將其與當前數字進行比較。但這要快得多。 – Lekensteyn 2010-12-04 13:59:47
@Lekensteyn這一切都取決於範圍的大小和你想要的不同值的數量。關於洗牌技巧的好處在於,它可以保證您不會陷入一個(不太可能,但可能)的循環中,在這個循環中您不斷從「隨機」功能獲取重複。 – Pointy 2010-12-04 14:01:11
真的好主意。然而,我不知道如何在Javascript中洗牌數組,介意給我一個樣本?謝謝。 – user435216 2010-12-04 14:04:25