在C#中随机生成字符串

3
我正在尝试随机排列字符串元素,但我的代码正在重复字符串。有人可以解释一下我的代码有什么问题吗?
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"

我遇到了单词重复的问题,并且它没有随机化。如果您不明白我的意思,请查看我在代码中添加的注释。非常感谢您的帮助!

可能是Randomize a List<T>的重复问题。 - Pac0
@Pac0,抱歉我没有看到那篇帖子。 :) - Katherine
当样本量较小时,“随机”存在问题。 - Sarvesh Mishra
1
@Nikol 没问题! - Pac0
1
@SarveshMishra:这里的问题不在于Random,而在于它的使用方式。 - Jon Skeet
@JonSkeet 同意,他只是想要洗牌。 - Sarvesh Mishra
2个回答

6
这是因为你正在做这件事情:重复使用相同的词语。
words[i] = words[currRandomNumber];

这行代码的意思是“将索引为currRandomNumber的单词复制到索引为i的位置”。只要icurrRandomNumber不同,就一定会有一个重复的单词。
你可能想做的是交换currRandomNumberi处的单词:
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]);

另一种方法是使用Fisher Yates洗牌算法,该算法确保每个排列出现的概率相等:

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);

2

或者,您可以将每个单词随机放入一个新列表中:

最初的回答

    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));    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接