随机算法在 C# 中无法正常工作

Random algorithm will not work properly in C#

我有一个程序可以创建给定数量的以文本文件命名的文件夹。我有以下算法:

private void button2_Click(object sender, EventArgs e)
{
    if (path != null && Directory.Exists(path))
    {
        Random rnd = new Random();
        for (int i = 0; i < value; i++)
        {
            var lines = File.ReadAllLines(path1);
            var randomLineNumber = rnd.Next(0, lines.Length);
            var line = lines[randomLineNumber];

            StringBuilder b = new StringBuilder();
            for (int j = 0; j < line.Length; j++)
            {
                char c = line[j];
                if (rnd.Next(2) == 0)
                {
                    c = Char.ToUpper(c);
                }
                b.Append(c);
                if (j % 2 == 1)
                {
                    b.Append(rnd.Next(10));
                }
            }
            line = b.ToString();

            Directory.CreateDirectory(Path.Combine(path, line));
        }
    }
}

我有一个文本文件,每行一个词。我的算法应该从中随机取一个词,并按照以下规则重命名我创建的文件夹:

lldlldll...ll 等等,其中:
l - 字母(大写或小写 - 它应该是随机的) d - 数字

实例:
文件夹数量:13

我的名单:

计算机
探索
无线


电气
phone
亚历克斯
安德鲁
电梯

期望输出:

aN5dR0ew7
dO1G6
DO3oR5
CO4mP7uT6er8
pH6ON1e
al9EX5
eX0pl9Or4e
EL5eC0Tr8iC0aL7
lO4vE2
wi1re9le6Ss47
el3eV0AT8oR9

实际输出:

aN5dR0ew7
dO1G6
DO3oR5
DO4G7
DO6g1
Do9G1
eL4Ec6TR5Ic3Al9
EL5eC0Tr8iC0aL7
eX2Pl6OR7E8
wi1re9le6Ss47
Wi8Re7Le6ss54

问题是下一个:

如果我创建了 20 个文件夹并且我在那个 .txt 文件中也有 20 个词,算法将不会使用所有的词,而只使用其中的一些词(它会重复它们 3 次)。数字没问题/上下字母没问题。我只需要确保该 txt 中的每个单词都会被使用。

有什么帮助吗?

无法保证 Random() 实例每次调用其 Next 方法时都会生成不同的值。 9 (nine) 是一个非常好的随机数,它可能是您在时间结束之前收到的全部。

你想要的是Fisher–Yates shuffle算法...你打乱了txt文件的行,所以你保证所有的行都被使用,并且每行只被使用一次。如果您需要的行数多于文件的行数,则每次用完文件的所有行时,您都会重新洗牌并重新启动。

这应该是完整的解决方案:

Random rnd = new Random();
var lines = File.ReadAllLines(path1);

for (int i = 0; i < value; i++)
{
    if (i % lines.Length == 0)
    {
        // We after using all the rows once
        // we used all of them (or at the beginning)

        // Shuffle, Fischer-Yates 
        int n = lines.Length;
        while (n > 1)
        {
            n--;
            int k = rnd.Next(n + 1);
            string value2 = lines[k];
            lines[k] = lines[n];
            lines[n] = value2;
        }
    }

    var line = lines[i % lines.Length];

    StringBuilder b = new StringBuilder();
    for (int j = 0; j < line.Length; j++)
    {
        char c = line[j];
        if (rnd.Next(2) == 0)
        {
            c = Char.ToUpper(c);
        }
        b.Append(c);
        if (j % 2 == 1)
        {
            b.Append(rnd.Next(10));
        }
    }
    line = b.ToString();

    Directory.CreateDirectory(Path.Combine(path, line));
} 

我会在这一行之后创建一个整数列表

var lines = File.ReadAllLines(path1);
List<int> list = Enumerable.Range(0, lines.Length).ToList<int>();

随机播放列表:Randomize a List<T>

循环播放打乱的台词

for (int i = 0; i < list.Count; i++) {
      var lineItem = lines[i];
}