Генерация случайных строк - два сгенерированных друг за другом дают одинаковые результаты

У меня есть простой фрагмент кода:

public string GenerateRandomString()
        {
            string randomString = string.Empty;
            Random r = new Random();
            for (int i = 0; i < length; i++)
                randomString += chars[r.Next(chars.Length)];

            return randomString;
        }

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

Ваш код даже не компилируется - а где остальное?

George Stocker 18.12.2008 01:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
1 641
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

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

Итак, на самом деле есть два решения.

1. Укажите свою исходную ценность, который будет уникальным каждый раз, когда вы создаете объект Random.

2. Всегда используйте один и тот же случайный объект. - построить только один раз.

Лично я бы использовал второй подход. Это можно сделать, сделав объект Random статическим или сделав его членом класса.

да, Random выбирает начальное семя на основе текущего времени, поэтому небольшая разница во времени даст то же семя.

Jimmy 18.12.2008 01:54

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

Paulius 18.12.2008 02:09

Просто наткнулся на это после нескольких часов попыток понять это, спасибо!

Nick Spiers 08.12.2009 21:43

Конструктор по умолчанию для Random (тот, который вы используете) заполняет генератор значением, основанным на текущем времени. Если время в миллисекундах не меняется между первым и вторым вызовом функции, будет использоваться одно и то же случайное начальное число.

Я предлагаю использовать статический объект Random и инициализировать его только один раз.

Это потому, что вы одновременно создаете два случайных объекта. Это дает ему то же семя, поэтому вы получите те же числа.

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

Приведенные выше ответы верны. Я бы посоветовал внести следующие изменения в ваш код:

1) Я бы предложил использовать StringBuilder вместо того, чтобы постоянно добавлять строку. Строки неизменяемы, поэтому каждый раз при добавлении к ней создается новая строка. Если вы никогда не использовали StringBuilder, поищите его. Это очень полезно для такого рода работы.

2) Вы можете упростить повторное использование вашего метода, если передадите длину в сам метод. Вы, вероятно, также могли бы передать массив символов, но я не упомянул об этом.

3) Используйте каждый раз один и тот же случайный объект, как было предложено выше.

public string GenerateRandomString(int length)
{
    StringBuilder randomString = new StringBuilder(length);

    for (int i = 0; i < length; i++)
        randomString.Append(chars[(int)(_RandomObj.Next(chars.Length))].ToString());

     return randomString.ToString();
}

Поскольку генератор Random привязан к системным часам, вы, вероятно, показываете те же результаты с этим периодом времени. Есть несколько способов исправить. Если вы используете петли, поместите Random rnd = new Random(); вне петли.

Поместите строку Random rnd = new Random();, в которой вы объявляете свои переменные, и используйте одну и ту же переменную во всей программе (rnd в этом примере).

Это сработает в большинстве случаев.

Другие вопросы по теме