'c#'에 해당되는 글 1건

  1. 2009.01.07 Random Class를 파해쳐 보자! (8)


어제 프로젝트 관련된 코딩을 하다가 난수를 써야 할 일이 있어서
C#의 Random Class에 관해 알아 보았다!

사실 Random Class의 사용방법은 그리 복잡하지도 어렵지도 않지만;
내가 만들고 싶은 난수가 적절히 만들어 지지 않아 몇시간을 테스트한김에
이와 관련된 포스팅을 하게 되었다;

예전 C언어나 C++의 rand() 함수를 사용할때는

int random = rand()%50;
위의 코드를 수행하게 되면 random 변수에는 에는 0부터 49까지 난수가 들어가게 된다;
rand()에sms seed 값이 있어 저렇게만 수행할 경우
만약 랜덤한 수가 1 3 6 2 6 순으로 나왔다면; 프로그램을 껏다 켜도 똑같은 패턴으로 나오게 된다;
그래서 아래의 항목을 추가하게 되면 그것을 막을 수 있었다;

srand(time(NULL)); // 시간에 따른 난수 발생, 없을경우 실행때마다 같은 난수가 발생한다.


이제 C# 의 Random Class를 보자;

사용법 정말 간단하다;

Random r  = new Random();

생성자는 오버로딩 되어있어 생성시 시드값을 정할수 있고! 정하지 않을수 있다;

정할경우 위에 말한대로 계속 똑같은 패턴의 난수가 발생하며 디폴트일 경우에는 시스템의 시간을 이용하여 
시드값을 정하기 때문에 매번 다른 패턴의 난수
가 발생한다;

제공하는 매소드를 알아보자;

r.Next() : 범위가 없는 랜덤한 값을 리턴한다
r.Next(int maxValue) : 난수의 범위의 상한을 지정
r.Next(int minValue, int maxValue) : 난수의 범위의 하한과 상한을 지정!


여기서 중요한것은 난수의 하한은 난수에 포함 되지만 상한은 포함 되지 않는다는것이다;
즉 1부터 10의 값을 난수로 얻고 싶을때 Next(1,10); 을 호출하면 10은 죽어도 안나온다는 말인다;;
10을 난수로 얻고 싶다면 Next(1,11)을 호출 해야한다;

그외에
r.NextBytes()
r.NextDouble() 
메소드가 있는데 int값만 필요해서 사용하지는 않았지만 메소드 명으로 쉽게 짐작 할수 있다;

이제 본론으로 들어가서 이렇게 간단한 Random Class의 사용방법을  포스팅을 하게 된 이유는
내가 발생하고 싶은 난수가 특정시간에 여러개의 객체를 생성할때 각각의 객체마다 다른 
난수를 가지고 있게 하고 싶었지만 Seed값을 기본적으로 시간을 사용하기 때문에 
할수가 없어서이다;

다음의 예제를 보면;

class Program
{
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Item item = new Item();
            }
        }
}

class Item
{
        int num1;
        int num2;
        public Item()
        {
            Random r = new Random();
            num1 = r.Next(1, 100);
            num2 = r.Next(100, 200);
            Console.WriteLine("{0} , {1}", num1, num2);
        }
}



매우 간단한 구조이다 Main()에서는 Item 객체를 10개 만들고 
Item 객체의 생성자에서는 난수를 2개 (각각 1~99, 100~199 범위의 값) 발생시켜
출력한다;

어떤 결과가 나올까? 10개의 객체는 각각 다른 난수를 가지고 있을까?

-- 실행 결과 --

결과처럼 '아니오' 이다; 

이와 같은 발생의 이유는 기본적으로 난수발생의 시드가 시간이기 떄문이다;
위에 예제처럼 빠르게 10개의 객체를 생성할 경우 시드가 같아져 같은 결과가 나오는것이다;

어떻게 해결할까?

밑의 두가지 예제의 차이를 알게되면 쉽게 해결 가능하다;
예제1)
Random
r = new Random();
for (int i = 0; i < 10; i++)
{
     Console.WriteLine("{0}", r.Next());               
}

예제2)
for (int i = 0; i < 10; i++)
{
     Random r = new Random();
     Console.WriteLine("{0}", r.Next());
}

--결과 화면--


화면에서 보다싶이 Random 객체를 빠르게 10번 생성한 예제 2에서는  같은 번호가 나왔고
객체를 재사용한 예제1에서는 다른 결과가 나왔다;


이 차이를 이용해 위에서 실패한 Item class에 랜덤한값을 배치 할수 있는것이다;

Random 객체를 static으로 두고 하나만 계속 사용한다면 위의 예제도 우리가 원하는 난수를 갖게 될것이다;

Posted by 맨날맑음
TAG , , ,

댓글을 달아 주세요

  1. hong 2010.06.03 20:30  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다.

  2. Favicon of https://blueasa.tistory.com BlogIcon blueasa 2010.07.16 17:36 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다. :)

  3. Favicon of https://spacechild.net BlogIcon 스페이스차일드 2010.10.20 10:03 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 잘 읽었습니다. 궁금한 것이 있는데요~ 코드와 관련된 게시물을 작성할 때, 가독성이 조금 걱정이 되는데, 제일 아래에 있는 알록달록 예쁜 코드는 코딩하실 때 모습 그대로 긁어서 붙이신 건가요? 어떤 어플리케이션을 추가로 사용하셨는지 궁금합니다 ^^

    • Favicon of http://crynut84.tistory.com BlogIcon 맨날맑음 2010.10.20 15:20  댓글주소  수정/삭제

      안녕하세요? 코드는 그대로 붙이는 것이 가장 간단하지만, 티스토리 에디터에 붙일 경우 색상이 날아가 버리는 경우도 있기 떄문에 저는 MS Word를 이용하여 포스팅 합니다. 본 포스팅은 이전에 작성한 것이기 때문에 일일이 색상을 지정하였습니다 ㅠ.ㅠ 그와 관련된 포스팅으로 아래 두개의 링크를 참조하세요.
      http://crynut84.tistory.com/4
      http://crynut84.tistory.com/76

  4. Favicon of https://spacechild.net BlogIcon 스페이스차일드 2010.10.20 16:04 신고  댓글주소  수정/삭제  댓글쓰기

    친절한 설명 감사합니다. 구글코드의 SyntaxHighlighter를 한번 설치해 보아야겠습니다 ^^

  5. 배드문 2020.07.18 19:31  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사!
    덕분에 랜덤 데이타 문제 해결했습니다.