随机算法在 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];
}
我有一个程序可以创建给定数量的以文本文件命名的文件夹。我有以下算法:
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];
}