我有一个包含几百行的文本文件,结构非常简单。
名 姓
我需要从文件中随机选择一个名字和姓氏并列出。
string[] lines = File.ReadAllLines(...); //i hope that the file is not too big
Random rand = new Random();
return lines[rand.Next(lines.Length)];
另一个(也许更好的)选项是使文件的第一行包含其中记录数,这样你就不必读取整个文件。
new Random()
,如果这些调用在时间上太接近,结果将不会随机。应该使用线程静态的 Random
。参见 Random number generator only generating one random number。 - dbc读取每一行时,保持一个计数器N,表示当前已经读取了多少行。以1/N的概率选择每一行,即第一行始终被选中,第二行被选中的概率为1/2,替换第一行,第三行为1/3,依此类推。这样每一行都有1/N的概率成为被选中的行,你只需要一次性读取文件,并且不需要在任何给定时间将整个文件存储在内存中。
下面是一个可以根据你的需求进行调整的实现。
public string RandomLine( StreamReader reader )
{
string chosen = null;
int numberSeen = 0;
var rng = new Random();
while ((string line = reader.ReadLine()) != null)
{
if (rng.NextInt(++numberSeen) == 0)
{
chosen = line;
}
}
return chosen;
}
基于一个C语言实现的代码 (链接),用于从任意长的链表中选择节点。
new Random()
,如果调用发生得太接近,结果将不是随机的。应该使用线程静态的 Random
。请参见 Random number generator only generating one random number。 - dbc