이 메소드가 매번 동일한 임의 문자열을 반환하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/807892

  •  03-07-2019
  •  | 
  •  

문제

작업중 인 다른 프로젝트를 테스트하기 위해 고유 한 라인 블록을 만들어야합니다.

그래서 나는 x 길이의 임의 문자열을 생성하는 간단한 프로그램을 만들었습니다.

문제는 한 번 호출하면 무작위 문자열이 발생한다는 것입니다. 다시 호출하면 (예를 들어 루프를 위해) 루프의 전체 실행에 대해 동일한 문자열을 얻습니다.

나는 그것이 캐시되고 있다는 느낌이 들지만 .NET가 그렇게 한 것을 몰랐고이 시점에서 혼란스러워합니다.

통화 코드 :

    StreamWriter SW = new StreamWriter("c:\\test.txt");
    int x = 100;
    while (x >0)
    {
        SW.WriteLine(RandomString(20));
        x--;
    }

방법은 다음과 같습니다.

private static string RandomString(int Length)
{
    StringBuilder sb = new StringBuilder();
    Random randomNumber = new Random();

    for (int i = 0; i <= Length; ++i)
    {
        int x = randomNumber.Next(65, 122);
        sb.Append(Convert.ToChar(x));
    }
    return sb.ToString();        
}

그리고 다음은 출력이 있습니다.

"VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
..................
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB
VEWMCQ`Fw]TvSFQawYnoB"

그렇다면 Random.next ()가 항상 새로운 임의의 숫자를 반환 할 것이라고 생각하는 이유는 무엇입니까?

도움이 되었습니까?

해결책

당신은 만들고 있습니다 Random 인스턴스가 너무 가깝습니다. 각 인스턴스는 시스템 클록을 사용하여 초기화되며 클록이 변경되지 않으므로 동일한 랜덤 숫자 순서를 반복해서받습니다.

단일 인스턴스를 만듭니다 Random 수업을 반복해서 사용하십시오.

사용 using 키워드를 통해 StreamWriter 완료되면 폐쇄되어 처분됩니다. 루프 코드는 사용하면 인식하기가 더 쉽습니다. for 예어.

using (StreamWriter SW = new StreamWriter("c:\\test.txt")) {
   Random rnd = new Random();
   for (int x = 100; x > 0; x--) {
      SW.WriteLine(RandomString(rnd, 20));
   }
}

이 방법은 Random 매개 변수로 객체.

또한 길이를 사용하여 루프 중에 재 할당 할 필요가 없도록 StringBuilder를 올바른 용량으로 초기화하십시오. 루프에서 <= 대신 <연산자를 사용하면 그렇지 않으면 하나보다 더 긴 문자열 인 문자열을 만듭니다. length 매개 변수가 지정됩니다.

private static string RandomString(Random rnd, int length) {
   StringBuilder sb = new StringBuilder(length);
   for (int i = 0; i < length; i++) {
      int x = rnd.Next(65, 122);
      sb.Append((char)x);
   }
   return sb.ToString();        
}

다른 팁

보다 랜덤 생성자 설명 MSN 에서이 부분 :

기본 종자 값은 시스템 클럭에서 파생되며 유한 해상도가 있습니다. 결과적으로, 기본 생성자에 대한 호출에 의해 밀접하게 연속적으로 생성되는 다른 임의의 개체는 동일한 기본 종자 값을 가지므로 동일한 임의의 숫자 세트를 생성합니다.

따라서 프로그램의 시작 부분에서 랜덤 () 생성자를 한 번만 호출하거나 랜덤 (int32) 생성자를 사용하고 다양한 시드를 직접 정의하십시오.

각 호출에 새 임의의 객체를 생성하기 때문입니다.

RandomNumber를 메소드에서 옮기고 클래스 멤버로 만듭니다.

private Random randomNumber = new Random();
private static string RandomString(int Length)
{
    StringBuilder sb = new StringBuilder();
    //...
}

모든 소프트웨어 랜덤 생성기는 '의사 랜덤'이며 (시작) 씨앗에서 일련의 숫자베이스를 생성합니다. 동일한 씨앗으로 동일한 시퀀스를 생성합니다. 때때로 이것은 유용합니다. 각 실행에 동일한 시퀀스를 생성하기 위해 프로그램을 제작하려면 사용할 수 있습니다. new Random(0).

편집 : 분명히 .NET 랜덤 클래스는 자동 시어링입니다. 나는 그것을 몰랐습니다. 따라서 다른 사람들이 지적했듯이 타이밍 문제입니다.

RandomNumber를 한 번만 선언하십시오



public class MyClass
{
    private static Random randomNumber = new Random();

    private static string RandomString(int Length)
    {
        StringBuilder sb = new StringBuilder();  

        for (int i = 0; i ... Length; ++i)
        {
        int x = MyClass.randomNumber.Next(65, 122);
        sb.Append(Convert.ToChar(x));
        }
        return sb.ToString();        
    }
}

임의의 숫자에 대한 씨앗은 짧은 시간이 걸리기 때문에 모두 동일합니다. 사실상 매번 동일한 시드로 임의의 생성기를 재현하므로 다음 () 호출은 동일한 랜덤 값을 반환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top