본문 바로가기
알고리즘

[JS] _.shuffle 구현

by 측면삼각근 2019. 11. 17.
728x90
반응형

코드스테이츠 shuffle기능의 구현을 정리한다.

기존에 나는 기존의 arrayList 를 받아 새로운 배열에 순서를 random하게 섞에 반환하는 코드를 다음과 같이 구현했었다. 코드는 복잡하지는 않지만 while(true)루트를 돌면서 stack에 부담이 큰것같다.

_.shuffle = function(array) {
  let arrayLength = array.length;
  let result = new Array(arrayLength);//길이만큼 return 용 새배열 선언
  for( let i = 0 ; i < arrayLength ; i++){//새배열의 Index를 하나 하나 돌면서
    while(true){//index 하나에 무한 한번씩 루프문에 들어가 랜덤한 수를 뽑으며 랜덤한 Index 배치한다.
      let num = Math.trunc( Math.random() * arrayLength );
      if(!result[num]) {//result에 값이 없다면 배치하고
        result[num] = array[i];
        break;//무한루프문을 종료한다.
      }
    }
  }

동기님들 덕분에 다른 여러가지 방법을 알게되어 정리!

1

// 1안
_.shuffle = function(array) {
  return array.slice().sort(_=>Math.random()-0.5);
}

sort 에서 return 시 Math.random(0~1까지의 수)-0.5를 하게된다면 -0.5~0.5까지의 50%의 확률로 양수, 혹은 음수가 반환된다 따라서 랜덤하게 shuffle된다.

하지만 위 방법은 정말 간단하지만, 파이거 커질수록 수의 suffle이 제대로 이루어지지 않아 지양해야 한다고 한다.

2

_.suffle = funciton(){
var newArray = array.slice();
   var valueHolder;
   var currentIndex = array.length - 1;  // 3
   var randomIndex;
   while (currentIndex) {
     randomIndex = Math.floor(Math.random() * currentIndex);  //random between 0 and 3  ** randomIndex does not produce random number
                                                              //every time it is called in this scope, it is set to one number for this
                                                              //single 'while' instance. So for this example, let's say randomIndex = 3
     currentIndex = currentIndex - 1;  // -> 2
     valueHolder = newArray[currentIndex];  // valueHolder = newArray[2] which is "3"
     newArray[currentIndex] = newArray[randomIndex]; // newArray[2]"3" = newArray[3]"4"   [1,2,3,4] => [1,2,4,4]
     newArray[randomIndex] = valueHolder; //newArray[random b/w 1-3 == 0]"1" = 4   ex) [1,2,4,4] ==> [1,2,4,3]
   }
}

어..내일 마저정리^^!

반응형