почему этот метод каждый раз возвращает одну и ту же случайную строку?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Мне нужно создать блок уникальных строк, чтобы протестировать другой проект, над которым я работаю.

Поэтому я создал простую программу для генерации случайной строки длины X.

Проблема в том, что если я вызову его один раз, я получу случайную строку, если я вызову его снова (например, в цикле for), я получу ту же строку для всего выполнения цикла.

У меня такое ощущение, что оно кэшируется или что-то в этом роде, но я не знал, что .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 class и используйте его снова и снова.

Использовать 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 эта часть:

Значение семян по умолчанию получено из системных часов и имеет конечное разрешение.В результате различные случайные объекты, которые создаются в тесной последовательности при вызове конструктора по умолчанию, будут иметь идентичные значения семян дефолта и, следовательно, будут создавать идентичные наборы случайных чисел.

Поэтому либо вызовите конструктор Random() только один раз в начале вашей программы, либо используйте конструктор Random(int32) и самостоятельно определите изменяющееся начальное число.

Потому что вы создаете новый объект Random при каждом вызове.

Просто переместите случайный номер из метода и сделайте его членом класса.

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

Все программные генераторы случайных чисел являются «псевдослучайными», они создают последовательность чисел на основе (начального) начального числа.С одним и тем же семенем они производят одну и ту же последовательность.Иногда это полезно.Если вы хотите, чтобы ваша программа создавала одну и ту же последовательность при каждом запуске, вы можете использовать new Random(0).

Редактировать:очевидно, что класс .Net Random автоматически заполняется, я этого не знал.Так что, как отмечали другие, это проблема времени.

объявляйте случайное число только один раз



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

все начальные числа для случайных чисел одинаковы из-за короткого промежутка времени, по сути, вы каждый раз заново создаете генератор случайных чисел с одним и тем же начальным числом, поэтому вызов Next() возвращает одно и то же случайное значение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top