3

I am trying to randomize string elements, but my code is repeating strings. Can someone explain what is wrong with my code?

string[] words = Console.ReadLine().Split();
//input = "Welcome and have fun learning programming"

Random number = new Random();

for (int i = 0; i < words.Length; i++)
{
    int currRandomNumber = number.Next(0, words.Length);
    words[i] = words[currRandomNumber];
}

Console.WriteLine(string.Join(' ', words));      
//output = "have learning learning learning learning programming"

I am facing problems with the words repeating, and it is not randomized? If you don't understand what I mean, see the comments which I added in the code. Any help will be appreciated!

Pac0
  • 21,465
  • 8
  • 65
  • 74
Katherine
  • 397
  • 2
  • 17

2 Answers2

6

The words are repeating because you are doing this:

words[i] = words[currRandomNumber];

The line means "copy the word at index currRandomNumber to the index i". As long as i and currRandomNumber are different, you are guaranteed to have a duplicate word.

What you meant to do was probably to swap the words at currRandomNumber and i:

var temp = words[i];
words[i] = words[currRandomNumber];
words[currRandomNumber] = temp;
// in C# 7, you could swap two values very easily by:
// (words[currRandomNumber], words[i]) = (words[i], words[currRandomNumber]);

Alternatively, you could use a Fisher Yates shuffling algorithm, which makes sure that each permutation have equal chances of occurring:

static void Shuffle<T>(T[] array)
{
    int n = array.Length;
    for (int i = 0; i < n; i++)
    {
        int r = i + _random.Next(n - i);
        T t = array[r];
        array[r] = array[i];
        array[i] = t;
    }
}

// Shuffle(words);
Sweeper
  • 213,210
  • 22
  • 193
  • 313
2

Alternatively, you can put each of the words into a new list in a random order:

    List<string> words = Console.ReadLine().Split().ToList();
    //input = "Welcome and have fun learning programming"

    Random number = new Random();
    var newwords = new List<string> ();

    while (words.Count > 0)
    {
        int currRandomNumber = number.Next(0, words.Count);
        newwords.Add( words[currRandomNumber]);
        words.RemoveAt(currRandomNumber);
    }

    Console.WriteLine(string.Join(' ', newwords));    
iakobski
  • 1,000
  • 7
  • 8