Pergunta

Eu preciso para criar um bloco de linhas exclusivas para testar um projeto diferente que eu estou trabalhando.

Então, eu criei um programa simples para gerar uma seqüência aleatória de comprimento X.

O problema é que se eu chamá-lo de uma vez, eu recebo uma seqüência aleatória, se eu chamá-lo novamente (em um loop, por exemplo) eu recebo a mesma seqüência para toda a execução do loop.

Eu tenho a sensação de que ele está sendo armazenada em cache ou algo assim, mas eu não sabia .net fez isso e eu estou apenas confuso neste momento.

código de chamada:

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

aqui é o método:

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();        
}

e aqui é a saída:

"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"

Então, o que dá eu pensei Random.next () sempre retornaria um novo número aleatório?

Foi útil?

Solução

Você está criando as instâncias Random muito perto no tempo. Cada instância é inicializado usando o relógio do sistema, e, quando o relógio não mudaram você obtém a mesma sequência de números aleatórios mais e mais.

Criar uma única instância da classe Random e usá-lo mais e mais.

Use a palavra-chave using para que o StreamWriter é fechado e descartado quando você é feito com ele. O código para um loop é mais fácil de reconhecer se você usar a palavra-chave 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));
   }
}

O método leva o objeto Random como parâmetro.

Além disso, use o comprimento para inicializar o StringBuilder com a capacidade correta, de modo que ele não tem de realocar durante o loop. Use o operador 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();        
}

Outras dicas

aleatória construtor descrição no MSN, esta parte:

O valor de semente padrão é derivado o relógio e sistema tem finita resolução. Como resultado, diferente objetos aleatórios que são criados em perto sucessão por uma chamada para o construtor padrão terá valores de sementes padrão idênticos e, por conseguinte, irá produzir conjuntos idênticos de números aleatórios.

Assim, ou chamar o construtor aleatório () apenas uma vez no início do seu programa ou usar o construtor (int32) aleatória e definir uma semente variando-se.

Como você cria um novo objeto Random em cada chamada.

Basta mover o randomNumber fora do método e torná-lo um membro da classe.

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

Todos os geradores de software são aleatórios 'pseudo aleatório', eles produzem uma sequência de números de bases sobre um (de partida) de sementes. Com a mesma semente que produzem a mesma sequência. Às vezes isso é útil. Se você quer produzir o seu programa para produzir a mesma seqüência em cada corrida, você pode usar new Random(0).

Edit: aparentemente, a classe Net aleatório é-semeadura auto, eu não sabia disso. Por isso, é um problema de tempo, como outros apontaram.

Somente declarar randomNumber uma vez



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();        
    }
}

a semente para os números aleatórios são todos iguais devido ao curto espaço de tempo que leva, na verdade você recriar o gerador aleatório com a mesma semente de cada vez, então a próxima () retorna o mesmo valor aleatório.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top