JavaScript를 사용하여 1에서 100 사이의 고유 한 난수를 생성하려면 어떻게 해야합니까?
답변
예 : 8 개의 고유 한 난수를 생성하여 배열에 저장하려면 다음과 같이하면됩니다.
var arr = [];
while(arr.length < 8){
var r = Math.floor(Math.random() * 100) + 1;
if(arr.indexOf(r) === -1) arr.push(r);
}
console.log(arr);
답변
- 1부터 100까지의 숫자로 배열을 채 웁니다.
- 셔플합니다 .
- 결과 배열의 처음 8 개 요소를 가져옵니다.
답변
100 개의 숫자 순열 을 생성 한 다음 순차적으로 선택합니다.
사용 크 누스 셔플 (일명 피셔 – 예이츠 셔플) 알고리즘 .
자바 스크립트 :
function fisherYates ( myArray,stop_count ) {
var i = myArray.length;
if ( i == 0 ) return false;
int c = 0;
while ( --i ) {
var j = Math.floor( Math.random() * ( i + 1 ) );
var tempi = myArray[i];
var tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
// Edited thanks to Frerich Raabe
c++;
if(c == stop_count)return;
}
}
수정 :
개선 된 코드 :
function fisherYates(myArray,nb_picks)
{
for (i = myArray.length-1; i > 1 ; i--)
{
var r = Math.floor(Math.random()*i);
var t = myArray[i];
myArray[i] = myArray[r];
myArray[r] = t;
}
return myArray.slice(0,nb_picks);
}
잠재적 인 문제점:
100 개의 숫자 배열이 있고 {예 : [1,2,3 … 100]} 8 번의 스왑 후 스와핑을 중지한다고 가정합니다. 그러면 대부분의 경우 배열은 {1,2,3,76,5,6,7,8, … 숫자가 섞여서 … 10}처럼 보일 것입니다.
모든 숫자는 1/100 확률로 교환되므로 확률이 높습니다. 처음 8 개 숫자를 교체하는 횟수는 8/100이지만 prob입니다. 다른 92 개의 스와핑은 92/100입니다.
그러나 전체 배열에 대해 알고리즘을 실행하면 (거의) 모든 항목이 스왑된다는 것을 확신합니다.
그렇지 않으면 우리는 어떤 8 개의 숫자를 선택해야할까요?
답변
답변
위의 기술은 라이브러리를 피하고 싶다면 좋지만, 라이브러리를 사용해도 괜찮을지 여부에 따라 JavaScript에서 임의의 항목을 생성 하는 기회 를 확인하는 것이 좋습니다 .
특히 질문을 해결하기 위해 Chance를 사용하면 다음과 같이 쉽습니다.
// One line!
var uniques = chance.unique(chance.natural, 8, {min: 1, max: 100});
// Print it out to the document for this snippet so we can see it in action
document.write(JSON.stringify(uniques));
<script src="http://chancejs.com/chance.min.js"></script>
면책 조항, Chance의 저자로서 나는 약간 편견이 있습니다.)
답변
길고 신뢰할 수없는 셔플을 피하기 위해 다음을 수행합니다.
- 순서대로 1에서 100 사이의 숫자를 포함하는 배열을 생성합니다.
- 1에서 100 사이의 난수 생성
- 배열의이 인덱스에서 숫자를 찾아 결과에 저장하십시오.
- 어레이에서 elemnt를 제거하여 더 짧게 만듭니다.
- 2 단계부터 반복하되 99를 난수의 상한으로 사용합니다.
- 2 단계부터 반복하되 난수의 상한으로 98을 사용합니다.
- 2 단계부터 반복하되 난수의 상한으로 97을 사용합니다.
- 2 단계부터 반복하되 난수의 상한으로 96을 사용합니다.
- 2 단계부터 반복하되 95를 난수의 상한으로 사용합니다.
- 2 단계부터 반복하되 난수의 상한으로 94를 사용합니다.
- 2 단계부터 반복하되 난수의 상한으로 93을 사용합니다.
Voila-반복되는 숫자가 없습니다.
누군가 관심이 있다면 나중에 실제 코드를 게시 할 수 있습니다.
편집 : 그것은 아마도 나에게 경쟁적인 연속이지만 @Alsciende의 게시물을 보았을 때 약속 한 코드를 게시하는 것을 거부 할 수 없었습니다.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>8 unique random number between 1 and 100</title>
<script type="text/javascript" language="Javascript">
function pick(n, min, max){
var values = [], i = max;
while(i >= min) values.push(i--);
var results = [];
var maxIndex = max;
for(i=1; i <= n; i++){
maxIndex--;
var index = Math.floor(maxIndex * Math.random());
results.push(values[index]);
values[index] = values[maxIndex];
}
return results;
}
function go(){
var running = true;
do{
if(!confirm(pick(8, 1, 100).sort(function(a,b){return a - b;}))){
running = false;
}
}while(running)
}
</script>
</head>
<body>
<h1>8 unique random number between 1 and 100</h1>
<p><button onclick="go()">Click me</button> to start generating numbers.</p>
<p>When the numbers appear, click OK to generate another set, or Cancel to stop.</p>
</body>
답변
또 다른 방법은 오름차순 숫자가있는 100 개 항목 배열을 생성하고 무작위로 정렬하는 것입니다. 이것은 실제로 매우 짧고 (내 의견으로는) 간단한 스 니펫으로 이어집니다.
const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));
