1580, 9/79 회원가입  로그인  
   kjwon15
   http://goo.gl
   배열 내에서 랜덤한 n개 추출하기

http://www.hackerschool.org/HS_Boards/zboard.php?id=Free_Lectures&no=1897 [복사]


가끔 프로그래밍을 하다가 랜덤한 숫자(혹은 다른 어떤것)이 필요할 때가 있습니다.
한개만 뽑으려면 rand()%<원하는 범위> 처럼 뽑으면 되지만 여러개를 뽑을때는 상황이 약간 달라집니다.

예를 들어 어떤 그룹에서 두명을 뽑아 승부를 겨루는 일이 있다고 해봅시다.
rand함수를 두번 돌리면 같은사람이 두번 뽑혀서 문제가 발생합니다.(자기자신과 승부를 하는건 의미가 없죠)
사실 여기까지는 간단합니다.

보통은 이렇게 하지요
player1=rand()%(전체_인원_수);
do player2=rand()%(전체_인원_수) while player1==player2

하지만 이렇게 하면 언제 끝날지 모릅니다.(큰 배열에서 2명이라면 거의 한번에 끝나지만 이런식으로 여러명을 뽑을때는 운이 안좋으면 시간이 엄청 걸립니다.)

불필요하게 다시 랜덤을 돌리는 일을 방지하려면 이렇게 하면 됩니다.
player1=rand()%(전체_인원_수);
player2=rand()%(전체_인원_수 - 1);
if(player2>=player1) player2+=1;

어떻게 한걸까요?
처음엔 그냥 평소대로 한명을 뽑습니다.
"뽑는다"라는 말 그대로 그 한명은 제외시켰다고 생각하는거죠
그 다음은 인원수-1만큼의 범위에서 랜덤을 돌렸습니다.(아까 한명이 빠졌기 때문에)
그리고나서 플레이어1보다 크거나 같은 경우 +1을 해 주었습니다.

사람 10명을 일렬로 세워놓았다고 합시다.
앞쪽부터 1,2,3...라고 이름을 지었습니다.
(1 2 3 4 5 6 7 8 9 10)
처음에 한명을 무작위로 뽑습니다.(저는 4번을 뽑았다고 할겁니다.)
그러면 1,2,3번은 그 위치에 있고 5,6,7,8,9,10번은 앞으로 한칸씩 오게 됩니다.
(1 2 3 5 6 7 8 9 10)
여기에서 4번째 부터는 자기 위치+1이 실제의 이름이 됩니다.
그래서 if(player2>=player1) player2+=1
라는 구문이 들어간겁니다.


이런식으로 랜덤한 2개의 변수를 뽑았습니다.
다만 3개 이상의 변수를 뽑으려면 이 방법으로는 상당히 복잡해지고 효율도 낮아집니다.
이때는 비슷하지만 다른 방법을 사용합니다.

  Hit : 12639     Date : 2011/12/05 03:17



    
havu 잘봤습니다 2012/01/10  
lawsoul 잘봤습니다. ~ 2012/04/20  
1420   I. 리눅스 구조 및 일반 명령어.     괴도js
07/04 12526
1419   [펌]스니핑[1]     loveaaav
03/24 12507
1418   * 해커가 되고싶나 ? *[19]     HackerMapia
03/01 12504
1417   초보가 적어본 윈도우 침투[6]     awsedr45
12/06 12493
1416   메모리 덤프(블루 스크린=STOP 스크린) 코드 및 해결[1]     ROK.AF
02/09 12464
1415   알기 어렵게 설명한 Buffer Overflow[4]     blackcoder
02/17 12398
1414   해킹기법? (기발하다고 해야하나,웃기다고 해야하나)[35]     whqkdnf000
07/31 12397
1413   c언어 for문      hacs98
06/15 12394
1412   [Reverse Engineering] 리버싱의 기초 - 범용 레지스터와 Assembly(Pop,Mov)     zen0c1de
07/18 12367
1411   C언어 기본구조[1]     괴도js
07/02 12305
1410   ping아는 카페 해킹 고수님에게 들은 소리입니다[21]     장세만
07/14 12304
1409   [펌]해커들의 흔적지우는방법[28]     starztp
10/08 12247
1408   개발자가 알아야할 10가지 보안팁으로 코드를 보호하자.     푸른하늘
09/01 12210
1407   C언어(진법)[9]     whqkdnf000
02/25 12199
1406   왠만한사람들은다알지도모르겠지만[6]     백룡출해
03/17 12107
1405   c++ 강좌[7]     jhon55
08/12 12051
1404   네트워크 개념 휘어잡기 7[8]     소유
09/16 11917
1403   [펌] 해킹의 역사     dzhfldk
08/22 11893
1402   trozan(트로이목마) 포트 목록[2]     whqkdnf000
02/22 11892
1401   리눅스 명령어 한꺼번에(소유님꺼)[11]     ssakura
07/07 11876
[1][2][3][4][5][6][7][8] 9 [10]..[79]

Copyright 1999-2023 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org & Wowhacker.com