[javascript] 1에서 100 사이의 고유 한 난수 생성

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. 1부터 100까지의 숫자로 배열을 채 웁니다.
  2. 셔플합니다 .
  3. 결과 배열의 처음 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 개의 숫자를 선택해야할까요?


답변

Set (및 평균 케이스 O (n))을 사용한 최신 JS 솔루션

const nums = new Set();
while(nums.size !== 8) {
  nums.add(Math.floor(Math.random() * 100) + 1);
}

console.log([...nums]);


답변

위의 기술은 라이브러리를 피하고 싶다면 좋지만, 라이브러리를 사용해도 괜찮을지 여부에 따라 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. 순서대로 1에서 100 사이의 숫자를 포함하는 배열을 생성합니다.
  2. 1에서 100 사이의 난수 생성
  3. 배열의이 인덱스에서 숫자를 찾아 결과에 저장하십시오.
  4. 어레이에서 elemnt를 제거하여 더 짧게 만듭니다.
  5. 2 단계부터 반복하되 99를 난수의 상한으로 사용합니다.
  6. 2 단계부터 반복하되 난수의 상한으로 98을 사용합니다.
  7. 2 단계부터 반복하되 난수의 상한으로 97을 사용합니다.
  8. 2 단계부터 반복하되 난수의 상한으로 96을 사용합니다.
  9. 2 단계부터 반복하되 95를 난수의 상한으로 사용합니다.
  10. 2 단계부터 반복하되 난수의 상한으로 94를 사용합니다.
  11. 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));