Why when generating random strings many of the string are the same/duplicated? [duplicate]

Chocolade 536 Reputation points
2023-01-03T08:49:31.32+00:00

First time i used the Random instance inside the method randStr and it generated many strings the same/duplicated.
so now i removed the random variable to the top and make one instance in the constructor.

but still i'm getting many strings the same/duplicated.
here is a screenshot with 3 examples of some strings that are the same i just scrolled down a bit each time.

275632-results2.jpg

MainWindow code

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Data;  
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Navigation;  
using System.Windows.Shapes;  
  
namespace Lab_ListView  
{  
    /// <summary>  
    /// Interaction logic for MainWindow.xaml  
    /// </summary>  
    public partial class MainWindow : Window  
    {  
        VideoGame vg = new VideoGame();  
        int counter = 0;  
        Random random;  
  
        public MainWindow()  
        {  
            InitializeComponent();  
  
            random= new Random();  
  
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;  
  
            System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();  
            dispatcherTimer.Tick += DispatcherTimer_Tick;  
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0);  
            dispatcherTimer.Start();  
        }  
  
        private void DispatcherTimer_Tick(object sender, EventArgs e)  
        {  
            vg.GameName = randStr(5) + " " + counter.ToString();  
            VideoGameListView.Items.Add(vg);  
            counter++;  
        }  
  
        public string randStr(int len)  
        {  
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";  
            return new string(Enumerable.Repeat(chars, len).Select(s => s[random.Next(s.Length)]).ToArray());  
        }  
    }  
}  

xaml code

<Window x:Class="Lab_ListView.MainWindow"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        xmlns:local="clr-namespace:Lab_ListView"  
        mc:Ignorable="d"  
        Title="Video Game List" Height="450" Width="800">  
    <Grid Margin="0,0,10,10">  
        <Label Content="Game Name" HorizontalAlignment="Left" Margin="40,59,0,0" VerticalAlignment="Top"/>  
        <TextBox x:Name="GameNameTextBox" HorizontalAlignment="Left" Height="23" Margin="121,62,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="366"/>  
        <Button x:Name="AddBtn" Content="Add" HorizontalAlignment="Left" Margin="121,151,0,0" VerticalAlignment="Top" Width="75" Click="AddBtn_Click"/>  
        <ListView x:Name="VideoGameListView" HorizontalAlignment="Left" Height="166" Margin="40,203,0,0" VerticalAlignment="Top" Width="447">  
            <ListView.View>  
                <GridView>  
                    <GridViewColumn Header="Game Name" DisplayMemberBinding="{Binding GameName}"/>  
                    <GridViewColumn Header="Rating" DisplayMemberBinding="{Binding Rating}"/>  
                    <GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}"/>  
                </GridView>  
            </ListView.View>  
        </ListView>  
        <Label Content="Rating" HorizontalAlignment="Left" Margin="40,90,0,0" VerticalAlignment="Top"/>  
        <Label Content="Price" HorizontalAlignment="Left" Margin="40,121,0,0" VerticalAlignment="Top"/>  
        <TextBox x:Name="PriceTextBox" HorizontalAlignment="Left" Height="23" Margin="121,123,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="366"/>  
        <TextBox x:Name="RatingTextBox" HorizontalAlignment="Left" Height="23" Margin="121,92,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="366"/>  
  
    </Grid>  
</Window>  

the VideoGame class code

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
  
namespace Lab_ListView  
{  
    class VideoGame  
    {  
        private string m_GameName;  
        private string m_Rating;  
        private double m_Price;  
  
        public string GameName  
        {  
            get  
            {  
                return m_GameName;  
            }  
  
            set  
            {  
                m_GameName = value;  
  
            }  
        }  
  
        public string Rating  
        {  
            get  
            {  
                return m_Rating;  
            }  
  
            set  
            {  
                m_Rating = value;  
  
            }  
        }  
  
        public double Price  
        {  
            get  
            {  
                return m_Price;  
            }  
  
            set  
            {  
                m_Price = value;  
  
            }  
        }  
  
        public VideoGame()  
        {  
            GameName = " ";  
            Rating = " ";  
            Price = 0.0;  
        }  
  
    }  
}  
  
Developer technologies | Windows Presentation Foundation
Developer technologies | XAML
Developer technologies | C#
{count} votes

2 answers

Sort by: Most helpful
  1. Viorel 122.6K Reputation points
    2023-01-03T09:20:29.58+00:00

    To reduce the duplicates, try adding one line:

    private void DispatcherTimer_Tick(object sender, EventArgs e)  
    {  
        vg = new VideoGame(); // ADDED  
        . . .  
    }  
    
    2 people found this answer helpful.
    0 comments No comments

  2. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-01-03T10:31:08.51+00:00

    You could generate an list of random strings with a capacity then get from the list as per below.

    public class Helper  
    {  
        private static  HashSet<string> HashSet;  
      
        public static void Initialize(int capacity)  
        {  
            HashSet = new HashSet<string>();  
            for (int index = 0; index < capacity; index++)  
            {  
                HashSet.Add(GenerateRandomString());  
            }  
        }  
      
        public static (bool success, string value) TryGet()  
        {  
            if (HashSet.Count > 0)  
            {  
                var value = HashSet.FirstOrDefault();  
                HashSet.Remove(HashSet.FirstOrDefault()!);  
                return (true,value)!;  
            }  
            else  
            {  
                return (false, null)!;  
            }  
        }  
        public static string GenerateRandomString(int length = 5)  
        {  
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
      
            var random = new Random();  
            return new string(Enumerable.Repeat(chars, length)  
                .Select(item => item[random.Next(item.Length)]).ToArray());  
        }  
      
    }  
    

    Initialize Helper.Initialize(20);

    Get a string, in this case I used a console app so you need to adjust to your code and note the list (HashSet) has 20 items, we try to get 25 but via assertion this is stopped, if more are needed call Helper.Initialize again or better initialize with more items than you may need.

    for (int index = 0; index < 25; index++)  
    {  
        var (success, value) = Helper.TryGet();  
        if (success)  
        {  
            Console.WriteLine($"{value} {_counter}");  
            _counter++;  
        }  
        else  
        {  
            Console.WriteLine("HashSet is empty");  
            break;  
        }  
    }  
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.