본문 바로가기

C programming/[Objection]

난수 생성 라이브러리

728x90
반응형

라이브러리

  • 난수를 생성하는 rand()함수가 반환하는 값은 0이상 (일반적으로) 32767  이하이다.
#include  <stdlib.h> rand()함수 사용 위함
#include  <time.h> time()함수 사용 위함

난수 생성 (컴파일 할 때마다 같음)

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#include  <time.h>
int main(){
    int n;
    for(int i=0;i<5;i++){
        printf("%d\n",rand());
    }
}
컴파일 할 때마다 같은 이유는 생성되는 난수의 순서, 즉 프로그램에서 첫 번째 생성되는 난수, 두 번째 생성되는 난수... 가 정해져있기 때문이다. 그 이유는 rand함수가 seed를 사용하여 난수를 실행하기 때문인데, 위의 프로그램은 프로그램을 실행할 때마다 seed값이 동일하기 때문에 동일한 패턴으로 난수를 만든다.

 

난수 생성: 시드 변경(컴파일 할 때마다 같음)

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#include  <time.h>
int main(){
    int n;
    srand(rand());
    for(int i=0;i<5;i++){
        
        printf("%d\n",rand());
    }
}
위의 코드를 실행하면 맨 처음의 코드의 결과값과는 다른데, 바로 srand 함수를 실행시켰기 때문이다. 하지만 이 코드를 실행시켜도 실행할 때 마다 값은 바뀌지 않는데, 처음 코드와 seed의 값만 바뀌었기 때문이다. 따라서 이를 해결하기 위해선 프로그램의 실행시간 마다 seed의 값을 변경해줘야 한다.

 

난수 생성: 시간 활용(컴파일 할 때마다 다름)

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#include  <time.h>
int main(){
    int n;
    srand(time(NULL));
    for(int i=0;i<5;i++){
        
        printf("%d\n",rand());
    }
}
위 코드를 time라이브러를 활용하여 프로그램 실행마다 다른 seed값을 주도록 했다. time(NULL)은 현재 시간을 매개변수로 주기 때문에 프로그램 실행마다 새로운 seed를 가지고 난수를 생성한다. 따라서 프로그램 실행마다 값이 변화하는 것을 알 수 있다.

 

!!!Tip 난수 생성 범위 제한

rand() % n
//0 ~ (n – 1) 범위의 난수를 생성한다.
/*
예 1) 0 ~ 1 사이의 정수 난수를 발생시키고 싶다면, rand() % 2로 호출.
예 2) 0 ~ 10000 사이의 정수 난수를 발생시키고 싶다면, rand() % 10001로 호출.
*/
rand() % n + m
//m ~ (n – 1 + m) 범위의 난수를 생성한다.
/*
예 1) 1 ~ 6 사이의 정수 난수(예: 주사위 눈수)를 발생시키고 싶다면, rand() % 6 + 1로 호출.
예 2) 1000 ~ 9999 사이의 정수 난수를 발생시키고 싶다면, rand() % 9000 + 1000으로 호출.
*/

 

((((long) rand() << 15) | rand()) % 1000000) + 1
- 1 ~ 1,000,000 범위의 난수를 생성한다.
- RAND_MAX = 32,767인 경우 이 수보다 큰 범위의 난수를 발생시키기 위한 방법: 32,767의 16진수 표현은 0X7FFF, 2진수 표현은 0111 1111 1111 1111이므로 rand() 호출은 15비트로 표현할 수 있는 난수를 반환한다.

이 값을 왼쪽으로 15비트만큼 shift해준 뒤 두번째 rand() 호출로부터 얻은 난수와 OR 연산을 해주면 30비트로 표현할 수 있는 난수를 얻을 수 있다. 이 난수의 범위는 0 ~ 1,073,741,823이며 이 값을 1,000,000으로 나머지 연산을 한 뒤 1을 더해주면 1 ~ 1,000,000 범위의 난수를 얻게 된다.

 

 

예제:  배열 a의 모든 요소의 순서를 뒤섞는 suffle 함수를 작성하라.

#include  <stdio.h>
#include  <string.h>
#include  <stdlib.h>
#include  <time.h>
#define swap(tmp, x,y)do{tmp = x; x = y; y=tmp;}while(0)
void suffle(int a[],int n){
    int fir,end,tmp;
    srand(time(NULL));
    for(int i=0;i<100;i++){
        do{fir  = rand()%90;}while(0>fir || fir > n);
        do{end  = rand()%90;}while(0>end || end > n);

        swap(tmp,a[fir],a[end]);
    }
}
int main(){
    int a[1000],cnt = 0;
    while(1){
        scanf("%d",&a[cnt]);
        if(a[cnt] < 0 ) break;
        cnt ++;
    }
    suffle(a,(cnt-1));
    for(int i=0;i<cnt;i++)printf("%d ",a[i]);
}
728x90
반응형

'C programming > [Objection]' 카테고리의 다른 글

유클리드 호제법: 재귀  (0) 2022.01.14
시간 측정 함수  (0) 2022.01.10
Shift 함수 / 시간 계산  (0) 2022.01.10
문자열 처리함수  (0) 2022.01.08
진수 변환  (0) 2022.01.05
댓글