question

HemanthB-9452 avatar image
0 Votes"
HemanthB-9452 asked JackJJun-MSFT answered

Generate a random string that wasn't previously generated c#

Hi, I want to generate random strings out of a list: So I used this code:
Random rnd = new Random();
List<string> validStrings = new List<string>() {
"Banana",
"Avocado",
"Grape",
"Apple", "Custard Apple",
"Cranberry" };
result = validStrings[rnd.Next(0, validStrings.Count)];
But I want it to generate only if that string wasn't previously already generated. So I tried using a listbox:

  private void GenerateRandom()
         {
             try
             {
                 Random rnd = new Random();
                 List<string> validStrings = new List<string>() {
                    "Banana",
                     "Avocado",
                    "Grape",
                    "Apple", "Custard Apple",
                 "Cranberry" };
                 result = validStrings[rnd.Next(0, validStrings.Count)];
                 if (!listBox1.Items.Contains(result))
                 {
                     generatedrandom = result;
                        
                     listBox1.Items.Add(result);
    
    
                 }
                 else
                 {
                       
                     GenerateRandom();
                 }
             }
             catch (Exception EX)
             {
                 MessageBox.Show(EX.ToString(), "EXCEPTION");
             }

But I get this exception: System.StackOverflowException
I understood that it infinitely looped the code and finally wasn't able to generate anything.

Please help

dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Viorel-1 avatar image
0 Votes"
Viorel-1 answered

Move the ‘Random rnd = new Random()’ line to class (form) level. This will solve one of issues.

In addition, make sure that the list box is not full, for example:

 if( listBox1.Items.Count >= validStrings.Count)
 {
    // no more valid strings
    return;
 }

Check an alternative function too:

 static readonly Random rnd = new Random( );
 static readonly List<string> validStrings = new List<string>
 {
    "Banana",
    "Avocado",
    "Grape",
    "Apple",
    "Custard Apple",
    "Cranberry"
 };
    
 private bool GenerateRandom( )
 {
    var unused_strings = validStrings.Except( listBox1.Items.Cast<string>( ) ).ToArray( );
    
    if( unused_strings.Length == 0 ) return false;
    
    string generated = unused_strings[rnd.Next( unused_strings.Length )];
    
    listBox1.Items.Add( generated );
    
    return true;
 }

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
0 Votes"
SimpleSamples answered

The trick is to remove each item from the list after having gotten it. First, yes, you need to do the new Random() only once each time. The other problem is that there is no need for recursion.

The following will generate a new list each time a button is pushed. Complete sample in Answers/GenerateRandom.

 public partial class Form1 : Form
 {
     string[] validStrings = new string[] {
         "Banana",
         "Avocado",
         "Grape",
         "Apple",
         "Custard Apple",
         "Cranberry"
         };

     public Form1()
     {
         InitializeComponent();
     }

     private void button1_Click(object sender, EventArgs e)
     {
         listBox1.Items.Clear();
         Random rnd = new Random();
         List<string> unchosen = new List<string>(validStrings);
         while (unchosen.Count > 0)
             GenerateRandom(unchosen, rnd);
     }

     private void GenerateRandom(List<string> unchosen, Random rnd)
     {
         try
         {
             string result = unchosen[rnd.Next(0, unchosen.Count)];
             unchosen.Remove(result);
             listBox1.Items.Add(result);
         }
         catch (Exception Ex)
         {
             MessageBox.Show($"Error: {Ex.Message}");
         }
     }
 }


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JackJJun-MSFT avatar image
0 Votes"
JackJJun-MSFT answered

@HemanthB-9452 , the exceptions means that your program are stuck in the Infinite loop when your listBox1 has the same elements with list validStrings .

Therefore, we need to jump out of the loop when we face the problem.

Here is a code example you could refer to.

 public void GenerateRandom()
         {
             try
             {
                 Random rnd = new Random();
                 List<string> validStrings = new List<string>() {
                     "Banana",
                      "Avocado",
                     "Grape",
                     "Apple", "Custard Apple",
                  "Cranberry" };
                 string generatedrandom = "";
                 var result = validStrings[rnd.Next(0, validStrings.Count)];
                 if (!listBox1.Items.Contains(result))
                 {
                     generatedrandom = result;
    
                     listBox1.Items.Add(result);
    
                 }
                 else if(listBox1.Items.Count==validStrings.Count)            //Added code here
                 {
                     MessageBox.Show("The list is filled with random string");
                     return;
                 }
                 else
                 {
                     GenerateRandom();
                 }
             }
             catch (Exception EX)
             {
                 MessageBox.Show(EX.ToString(), "EXCEPTION");
             }
         }
    
         private void button1_Click(object sender, EventArgs e)
         {
             GenerateRandom();
         }


If the response is helpful, please click "Accept Answer" and upvote it.


Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.