2010. 9. 26. 19:23

프로그램을 구현하다 보면 난수(Random Number)를 발생시켜야 하는 경우가 종종 있다. 여기서 말하는 난수란 임의의, 정해지지 않은, 무엇이 될지 모르는 수를 의미하는 것으로 무작위로 값을 생성해야 함을 의미한다.

ANSI표준에서는 이렇게난수를 생성할 때 사용할 수 있는 함수 rand를 제공하고 있다.

다음 예에서는 rand 함수의 사용 방법과 난수의 범위를 보여준다.
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
     int i;

     printf("난수의 범위 : 0부터 %d까지\n", RAND_MAX);

     for(i = 0; i < 5; i++)
          printf("난수 출력 : %d \n", rand() );

     return 0;
}



위의 예제를 여러 번 돌려보면 한가지 특징을 발견할 수 있다. 그것은 발생하는 난수가 규칙적이라는 것이다.
예를 들어서 처음 실행했을 때 생성된 난수가 21, 1, 43, 13, 2라면 다시 실행해 봐도 생성되는 난수는 21, 1, 43, 13, 2가 생성된다는 것이다. 이는 분명히 문제다! 왜냐하면 진짜로 난수가 생성되는 것이 아니기 때문이다. 따라서 rand 함수를 가리켜 의사 난수(pseudo-random number)를 생성하는 함수라고 하는 것이다. 의사 난수라는 뜻은 가짜 난수를 의미한다.

물론 여기에는 대안이 있다. srand함수를 사용하는 것이다.
#include <stdlib.h>

void srand( unsigned int seed );

함수 srand는 하나의 인자를 전달받는다. 이 인자를 가리켜 씨드(seed) 값이라 한다. 씨드란 씨앗이라는 뜻이다. 즉 난수 생성을 위해 씨앗을 심는 용도로 사용되는 함수이다. "콩 심은 데 콩 나고, 팥 심은 데 팥 난다."는 속담이 있듯이 씨드 값이 무엇이냐에 따라서 rand 함수 호출 시 생성되는 난수들은 달라지기 마련이다.

다음 예제는 씨드값을 입력 받아서 srand 함수를 호출하는 예제이다.
#include < stdio.h >
#include < stdlib.h >

int main(void)
{
     int seed, i;
 
    printf("씨드 값 입력: ");
    scanf("%d", &seed);
    srand(seed);    //씨앗을 심는다.
   
    for( i = 0; i < 5 ; i++)
        printf("정수 출력: %d \n", rand()); //열매를 수화ㅏㄱ한다.

    return 0;
}



srand 함수도 공부했으니 이제 진정한 난수를 발생시킬 수 있겠는가?
아니다!! 여전히 문제는 있다. 위 예제처럼 프로그램을 실행할 때마다 씨드 값을 입력받을 수는 없는 노릇 아닌가? 설사 입력받는다 해도 매번 다른 값을 입력받는다는 가정을 세우는 것도 무리가 있다. 한가지 방법은 있다. 시스템의 시간을 이용하는 것이다. 현재 여러분 컴퓨터의 시간 값을 얻어와서 srand 함수의 인자로 전달할 수만 있다면 문제는 해결이 된다. 왜냐하면 컴퓨터의 시간은 계속해서 변하기 때문이다.

그렇다면 컴퓨터의 현재 시간을 어떻게 얻어와야 할까? 헤더파일 time.h 에 선언되어 있는 time이라는 이름의 함수를 사용하면 된다. 이 함수는 컴퓨터의 현재 시간과 1970년 1월 일 이후의 시간적 차를 초 단위로 계산하여 반환해 준다(굉장하지 않은가?) 우리는 정확한 시간을 얻겠다는 것이 아니고, 프로그램 실행시 마다 변경되는 값을 얻겠다는 것이므로, 이 정도면 충분하다.


지금까지 이야기한 내용을 종합하여 진정한 난수를 발생시키는 예를 제시하겠다. 실행해 보면 매번 출력되는 난수의 값이 다르다는 것을 알 수 있을 것이다.
#include < stdio.h >
#include < stdlib.h >
#include < time.h >

int main(void)
{
    int i;
    srand( (int) time (NULL) ); //현재 시간을 이용해서 씨드 설정
    for( i = 0; i < 5; i++ )
        printf("정수 출력 : %d \n", rand() );

    return 0;
}


출처 :  C프로그래밍 _ 윤성우 저
Posted by Triany
2010. 9. 26. 18:38

유클리드의 호제법은 소인수분해가 쉽지 않은 '양의 정수'의 최대공약수를 쉽게 구할 수 있는 방법이다.
예를 들어 589와 713의 최대공약수는 쉬워 보이지 않는다.
그러나 유클리드의 호제법을 이용하면 쉽게 풀 수 있다.
유클리드의 호제법은 나머지가 '0'이 될 때까지 나누고 또 나누는 과정을 되풀이 한다.


그렇다면 713과 589의 최대공약수를 유클리드의 호제법을 이용해 한번 풀어 보자.

713 % 589 = 1 ..... 124  -----①
589 % 124 = 4 ..... 93   -----②
124 % 93   = 1 ..... 31   -----③
93   % 31   = 3 ..... 0    -----④

∴ 713과 589의 최대공약수는 31이다.


이러한 방법으로 최대공약수를 구하면 쉽게 구할  수 있다.


출처 : 소설처럼 아름다운 수학 이야기_김정희 지음

간단한 C코드

#include <stdio.h>

int GCMU(int num1, int num2);
int main(void){
  int num1, num2, result;
 printf("2)최대공약수를 출력하는 프로그래밍을 작성해 보자\n");
 printf("두 정수를 입력하여라 : ");
 scanf("%d   %d", &num1, &num2);
 result = GCMU(num1, num2);
 printf("%d와 %d의 최대공약수는 %d입니다.\n", num1, num2, result);

 return 0;
}
int GCMU(int num1, int num2)
{
 if(num2 == 0 ) return num1;
 else
  return GCMU(num2, num1 % num2);
}

'책갈피 > 수학/과학' 카테고리의 다른 글

슈뢰딩거의 고양이  (0) 2011.02.08
Posted by Triany
2010. 9. 25. 18:16
기다리던 드라마 ost CD가 왔다 -. mp3에 넣고 듣고 다닐려고 보니 CD 오디오 트랙 형식.
CD 오디오 트랙 형식을 mp3로 변경하기 위한 쉬운 방법은 Windows Media Player를 이용하는 방법이다.
(주의 : 구 버전에는 리핑기능이 없다. 나도 이 김에 윈도우미디어플레이어 11로 업데이트 하였다.)

1. WMP를 키고, 리핑 탭으로 들어간다.


2. 리핑의 형식은 mp3로 체크한다. 


3. 비트 전송률을 조정한다.(나는 320Kbps-최고음질)로 조정하였다.



4. 하단의 리핑 시작 버튼을 누르면 OK!


리핑된 mp3파일은 My Documents(내문서) - 내 음악 에 저장된다.
꽤 간단한 방법인듯^^



Posted by Triany