달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

'중복'에 해당되는 글 1건

  1. 2010.07.08 [C++/C] 중복되지 않게 랜덤 숫자 출력

1 ~ 100 까지 랜덤하게 숫자를 뽑을때 중복되지 않게 뽑으면서 속도까지 빠르려면 어떤 방법이 있을까??

일반적으로 사실 for문 을 잘 돌리면 중복 되지 않게 뽑는건 어렵지 않다..
다만 중복 for문에 의해 속도가 느려질뿐... 1 ~ 10 정도의 작은 수는 괜찮지만 1000, 10000 같이 숫자가 커질수록 부하는 몇배로 커진다...

우선 한가지 생각해본 방법은
미리 배열에 1 ~100까지 담아두고 하나씩 빼오는 것.
그러다 이미 빠진 숫자가 나오면 그 옆의 숫자를 가져오는 것을 생각해봤다.

IString arrNum[100];
for(int i = 1 i < 101; i++)
{
  arrNum[i] = i+1;
}
for(int i = 1; i < 101; i++)
   {
    sTemp = (short)rand() % 100 ;
    while(arrNum[sTemp].Compare("")==0)
    {
     sTemp++;
     if(sTemp == 100) sTemp = 1;
    }
    arrNum[sTemp] = "";
   }
printf("%d", sTemp);

①②③④⑤⑥⑦⑧⑨⑩....... 이렇게 100까지 저장해 둔다.

랜덤을 돌려서 5가 나오면
①②③④""⑥⑦⑧⑨⑩.......   5는 공백이 된다.

쭉 for문을 돌다가 또 5가 나오면 그 옆 숫자인 6을 가져오고.. 6도 비어있으면 그 옆의 7... 이런식으로 한칸 옆의 숫자를 가져오면서 돌게 된다.


하지만 위 코드도 단점이 있었다..
낮은 확률이긴 하지만 마지막에 가면 근접한 숫자들이 뭉쳐서 나올때가 있다.


그래서 검색을 하고 하고 또 해서 찾아낸 방법.
int sCard = 100;
int *x = new int[sCard];
   for (int j = 0 ; j < sCard; j++)
    x[j] = j;
   
   for (int j = 0; j < sCard; j++)
   {
    int tmp = 0;
    int k = 0;
    int l = 0;
    for(int m = 0; m < 8; m++)
    {
     tmp += rand() << (32 - ((m + 1) * 4));
    }
    k = (tmp % (sCard - j)) + j;
    l = x[j];
    x[j] = x[k];
    x[k] = l;
   }
   free(x);


아참.. 위 코드는 0~ 100이 되겠다..
인덱스 가져올 일이 있어서 0 부터로 짯음...

사실 소스에서
 for(int m = 0; m < 8; m++)
    {
     tmp += rand() << (32 - ((m + 1) * 4));
    }
    k = (tmp % (sCard - j)) + j;


이부분은 이해를 못하고 있다..
먼가 중요한 부분이고 위 소스 때문에 난수가 제대로 나오는것 같은데 아직 정확히 이해는 못하고 있다 ;ㅁ;

'프로그래밍 > C++ / C' 카테고리의 다른 글

[c++] CHttpConnection에서 한글 전송 시 null 문제  (0) 2011.01.13
[C++/C] 트랜잭션 ...  (0) 2010.12.23
Posted by SadDev
|