Случайное число в цикле Do While

#c# #random #while-loop #do-while #random-seed

#c# #Случайный #цикл While #do-while #случайное начальное значение

Вопрос:

Я пытался создать случайную строку из буквенно-цифровых символов и использовать цикл Do-While, чтобы проверить, соответствует ли случайная строка требованиям. В противном случае цикл Do следует продолжить. Однако я обнаружил, что код, который у меня всегда генерирует одну и ту же строку снова и снова. Чтобы продемонстрировать, я устанавливаю int message_length = 2 и прошу цикл While проверить, похожа ли сгенерированная строка на «ab» while (check != "ab") .

Я попытался поместить Random seed = new Random() в цикл Do, из цикла Do и из Main(), как вы можете видеть код, который я прокомментировал. Ни один из них не работает. Я использовал Visual Studio 2017, Windows 10 Home. Кто-нибудь может помочь? Большое спасибо!

(Дополнительные комментарии: хотя сейчас код работает нормально, я все еще не понимаю, почему исходная строка check = all_message.ToString(); может прервать генератор случайных чисел в этом случае. ИМХО, условие while while (check != "ab") по-прежнему верно, поэтому цикл будет продолжаться. Но почему генератор случайных чисел перестает генерировать новое начальное значение? Кто-нибудь может поделиться знаниями об этом?

 using System;
using System.Text;
using System.Collections.Generic;


public class Program
{
    //static Random seed = new Random();

    public static void Main(string[] arggs)
    {
        Random seed = new Random();
        const string src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Console.WriteLine(src.Length);
        int string_length = 2;
        List<string> all_message = new List<string>();
        string check = "";
        do
        {
            //Random seed = new Random();
            int i = 0;
            StringBuilder message = new StringBuilder();
            for (int j = 0; j < string_length; j  )
            {
                char c = src[seed.Next(0, src.Length)];
                message.Append(c);
            }
            all_message.Add(message.ToString());
            check = all_message.ToString();
            Console.WriteLine(i   " = "   all_message[i]);

            i  ;
        }
        while (check != "ab");

    }
}
  

Комментарии:

1. check = message.ToString(); ? TBH, неясно, что вы пытаетесь сделать.

2. Спасибо за быстрый ответ. Тип all_message является StringBuilder . Поэтому мне нужно check = message.ToString() преобразовать его в строковый тип.

3. @JohnnyMopp не путайте OP — all_message.ToString(); — не «преобразует список в строку», а просто «возвращает имя типа списка»… (которое, очевидно, никогда не будет «ab», но это для OP для отладки)

4. 2 вещи: 1. check будет ВСЕГДА быть ‘System. Коллекции. Generic.Перечислите 1[System.String]' (yes, that string literally). I don't think it's doing what you think it's doing. 2. Why do you think your loop is generating the same string? Just put a breakpoint where you assign c` и посмотрите, изменится ли он. Держу пари, что так и есть.

5. Используйте свой отладчик , чтобы посмотреть, что check есть. Это не то, что вы думаете. Мы не можем помочь, потому что не понимаем, что вы пытаетесь сделать. A List<string> никогда не может быть равно ab .

Ответ №1:

Вы сбрасываете свой счетчик ‘i’ на каждой итерации цикла, поэтому вы всегда будете записывать первый элемент сгенерированного списка в консоль. Инициализируйте i вне цикла.

Ответ №2:

С помощью других я разобрался в проблеме. Критическое изменение check = string.Join("", all_message.ToArray()); . С несколькими другими незначительными изменениями, решения здесь:

 using System;
using System.Text;
using System.Collections.Generic;


public class Program
{
    //static Random seed = new Random();

    public static void Main(string[] arggs)
    {
        Random seed = new Random();
        const string src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Console.WriteLine(src.Length);
        int string_length = 2;
        string check = "";
        int i = 0;
        do
        {
            //Random seed = new Random();
            List<string> all_message = new List<string>();

            StringBuilder message = new StringBuilder();
            for (int j = 0; j < string_length; j  )
            {
                char c = src[seed.Next(0, src.Length)];
                message.Append(c);
            }
            all_message.Add(message.ToString());
            check = string.Join("", all_message.ToArray());
            //Console.WriteLine(check);
            Console.WriteLine(i   " = "   check);

            i  ;
        }
        while (check != "ab");

    }
}
  

Ответ №3:

Подсказка: прочитайте комментарии.

         Random seed = new Random();
        const string src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Console.WriteLine(src.Length);
        int string_length = 2;
        List<string> all_message = new List<string>();
        string check = "";
        do
        {
            //Random seed = new Random(); -- you do not need it any more hier.

            int i = 0; // if you whant counting with i, put it above the do while.

            StringBuilder message = new StringBuilder();

            for (int j = 0; j < string_length; j  )
            {
                char c = src[seed.Next(0, src.Length)];
                message.Append(c);
            }


            all_message.Add(message.ToString());

            check = all_message.ToString(); // this is the list from string you do not need it realy and list to string  = System.Collections.Generics.List....
            //instead check should be equal to all_message[i] case i counting properly

            Console.WriteLine(i   " = "   all_message[i]); // and hier simply print the check, you allready have the value.

            i  ;
        }
        while (check != "ab");
  

Ответ №4:

Я запустил следующее:

 Random seed = new Random();
const string src = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Console.WriteLine(src.Length);
int string_length = 2;
List<string> all_message = new List<string>();
string check = "";
int i = 0;
do
{
    //Random seed = new Random();
    
    StringBuilder message = new StringBuilder();
    for (int j = 0; j < string_length; j  )
    {
        char c = src[seed.Next(0, src.Length)];
        message.Append(c);      
    }   
    all_message.Add(message.ToString());
    check = all_message.ToString();
    Console.WriteLine(i   " = "   all_message[i]);
    i  ;
}
while (i < 3);
  

Мой вывод был:

 62
0 = PQ
1 = xw
2 = he
  

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

Тогда возникает вопрос, каковы ваши требования и когда завершать цикл и что должно check быть?