2011-10-05 3 views
2

여기 거래가 있습니다.무작위가 아닌 무작위, Windows Phone 7의 무작위 클래스

50 개의 따옴표가있는 배열이있는 wp7 용 앱을 설정했습니다. 사용자가 버튼을 클릭하면 배열의 임의의 인용 부호가 표시됩니다. 문제는 따옴표가 항상 같은 순서로 나타나는 것입니다. 예를 들어, 따옴표는 1-50입니다. 순서는 항상 2, 4, 20, 31, 10, ... 해결 방법이 있습니까? 앱을 사용할 때마다 무작위로 다른 따옴표가 표시되기를 바랍니다.

string[] listaCantadas; 
    Random r1, r2; 

    public MainPage() 
    { 
     InitializeComponent(); 

     listaCantadas = new string[] 
     {"//set of quotes 
     }; 

     r1 = new Random(100); 
     r2 = new Random(r1.Next(0, 50)); 
    } 

    //click event for display a random quote 

      int Cantada = r2.Next(0, listaCantadas.Length - 1); 
      txtBlockCantada.Text = listaCantadas[Cantada]; 

     }); 
    } 

답변

14

Random의 첫 번째 인스턴스는 Random(100) 즉 상수 시드로 만듭니다. 그래서 항상 동일한 순서를 반환합니다. 즉, Random의 두 번째 인스턴스의 시드도 일정하며 모든 값도 반환된다는 것을 의미합니다.

기본 생성자가 new Random()Random이라는 단일 인스턴스를 만듭니다. 이것은 시간과 함께 뿌려지기 때문에 프로그램 실행마다 다를 수 있습니다.

경고 : 기본 생성자가 빠른 연속으로 Random 인 여러 인스턴스를 만드는 경우 시간이 단지 몇 밀리 초 (일반 Windows 컴퓨터의 경우 1 ~ 16 밀리 초)마다 변경되기 때문에 대부분 같은 시퀀스를 반환합니다.

또 다른 일반적인 함정은 Random이 스레드로부터 안전하지 않다는 것입니다. 그러나 당신이이 문제에 부딪 힐 것 같지 않습니다.

string[] listaCantadas; 
Random r;//No need for more than one instance 

public MainPage() 
{ 
    InitializeComponent(); 

    listaCantadas = new string[] 
    {"//set of quotes 
    }; 

    r = new Random(); 
} 

//click event for display a random quote 

     int Cantada = r.Next(0, listaCantadas.Length - 1); 
     txtBlockCantada.Text = listaCantadas[Cantada]; 

    }); 
} 
+0

정말 고마워요, 이제는 매력처럼 작동합니다 !!! – Boga

+0

** ** 정적 인 인스턴스로 만듭니다. –

+3

@ ClausJørgensen : 음, 여러 스레드에서 호출하지 않도록주의하십시오. 일반적으로 정적 멤버는 스레드로부터 안전해야합니다. 'Random' *은 스레드로부터 안전하지 않습니다. –

1

같은 씨앗 모든 시간을 파종하고 있습니다 :

여기에 코드입니다. 그냥 new Random()을 사용하십시오. WP7에서 사용할 수 없다면 현재 시간의 미분을 시드로 사용하십시오.

0

동일한 종자가 있습니다. 현재 날짜에서 생성 된 번호와 같은 것을 사용하십시오.

r1 = new Random(DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Second); // etc 
+3

아니면 그냥'new Random()'을 호출하면됩니다 ... –

1

시드는 항상 동일하며 다른 임의 문자로 초기화됩니다. 당신이 반복 시퀀스를 원하지 않는

new Random(unchecked((int) (DateTime.Now.Ticks))); 
+0

이것은'Random'의 기본 생성자를 사용하는 것보다 나쁩니다. 기본 생성자와 동일한 문제가 발생하고 'Ticks'를 사용하여 시드 공간을 제한하는 추가 문제가 발생합니다. – CodesInChaos

2

당신은 고정 씨앗과 임의의 발전기를 씨앗 안 :

시도하는 또 다른 방법 파종

new Random(100); 

이어야를

new Random(); 
4

명시 적으로 씨앗을 말하고 있습니다 :

r1 = new Random(100); 
r2 = new Random(r1.Next(0, 50)); 

r1 항상 같은 씨앗 (100)를 사용, 그래서 r1.Next(0, 50) 항상 같은 씨앗을 줄 것이다, 그래서 r2 항상 같은 씨앗을 사용합니다. 당신은 아무런 난수가 없습니다.

Random의 단일 인스턴스를 만들고 다시 사용하는 것이 좋습니다. 반면 Random은 스레드로부터 안전하지 않습니다. UI 스레드에서 인스턴스 만 사용하려는 경우에는 문제가 없습니다.)

자세한 내용은 내 article on random number generation in .NET을 참조하십시오.

2

그럼 r1 랜덤 라이저에서 항상 씨앗을 100으로 초기화했습니다. 그것은 물론 씨앗에 따르면 항상 같은 숫자를 얻게된다는 것을 의미합니다. 즉, r2는 항상 동일한 시드로 초기화되므로 r1과 r2는 항상 동일합니다.

PC의 경우이 숫자만큼 이상한 숫자는 불가능합니다. 따라서 임의 생성기를 초기화하려면 "임의"숫자가 필요합니다.

짧은 이야기. 첫 번째 임의의 개체를 제거하고 두 번째 빈 constructor 빈을 사용하십시오.

기본 시드 값은 시스템 클럭에서 파생

0

단순히 다음 코드를 사용하여 유한 해상도를 가지고있다;

Random r = new Random(); 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      string[] listaCantadas = 
      { 
       "q1", 
       "q2", 
       "q3", 
       "q4", 
       "q5" 
      }; 

      //click event for display a random quote 
      txtBlockCantada.Text = listaCantadas[r.Next(0, listaCantadas.Length)]; 
     }