Question

Je dois créer un bloc de lignes uniques pour tester un projet différent sur lequel je travaille.

J'ai donc créé un programme simple pour générer une chaîne aléatoire de longueur X.

Le problème est que si je l’appelle une fois, je reçois une chaîne aléatoire. Si je l’appelle de nouveau (dans une boucle for par exemple), je reçois la même chaîne pour l’exécution complète de la boucle.

J'ai l'impression qu'il est mis en cache ou quelque chose du genre, mais je ne savais pas que .net l'avait fait et je suis tout simplement dérouté à ce stade.

code d'appel:

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

voici la méthode:

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

et voici la sortie:

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

Alors, qu'est-ce qui donne à penser que Random.next () renverrait toujours un nouveau nombre aléatoire?

Était-ce utile?

La solution

Vous créez les Random instances trop proches dans le temps. Chaque instance est initialisée à l’aide de l’horloge système. L’horloge n’ayant pas changé, vous obtenez la même séquence de nombres aléatoires à plusieurs reprises.

Créez une seule instance de la using classe et utilisez-la encore et encore.

Utilisez le mot-clé StreamWriter pour que le for soit fermé et supprimé lorsque vous avez terminé. Le code d'une boucle est plus facile à reconnaître si vous utilisez le length mot clé.

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

La méthode prend l'objet <=> en paramètre.

Utilisez également la longueur pour initialiser StringBuilder avec la capacité correcte, de sorte qu'il ne soit pas nécessaire de réaffecter les ressources pendant la boucle. Utilisez le & Lt; opérateur à la place de < = dans la boucle, sinon vous créerez une chaîne dont la longueur est supérieure à celle spécifiée par le paramètre <=> spécifié.

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

Autres conseils

Voir la Description du constructeur aléatoire sur MSN, cette partie:

  

La valeur de départ par défaut est dérivée de   l'horloge système et a fini   résolution. En conséquence, différents   Objets aléatoires créés dans   succession proche par un appel à la   constructeur par défaut aura   valeurs de départ par défaut identiques et,   donc, produira des ensembles identiques   de nombres aléatoires.

Donc, appelez le constructeur Random () une seule fois au début de votre programme ou utilisez le constructeur Random (int32) et définissez vous-même une graine variable.

Parce que vous créez un nouvel objet aléatoire à chaque appel.

Il suffit de déplacer le randomNumber de la méthode et d'en faire un membre de la classe.

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

Tous les logiciels Les générateurs aléatoires sont «pseudo aléatoires», ils produisent une séquence de nombres basée sur une graine (de départ). Avec la même graine, ils produisent la même séquence. Parfois, c'est utile. Si vous voulez que votre programme produise la même séquence à chaque exécution, vous pouvez utiliser new Random(0).

Edit: apparemment, la classe .Net Random est auto-ensemencée, je ne le savais pas. C’est donc un problème de synchronisation, comme d’autres l’ont souligné.

déclarer seulement randomNumber une fois



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

les valeurs initiales des nombres aléatoires sont toutes identiques en raison de la brièveté du temps nécessaire. En fait, vous recréez le générateur aléatoire avec la même valeur initiale à chaque fois, de sorte que l'appel Next () renvoie la même valeur aléatoire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top