从文件中读取随机行?C#

cra*_*rap 7 .net c# file

我有一个几百行的文本文件,结构很简单.

名字姓氏

我需要从文件中挑选一个随机的firstname和listname.

Ita*_*aro 15

string[] lines = File.ReadAllLines(...); //i hope that the file is not too big
Random rand = new Random();
return lines[rand.Next(lines.Length)];
Run Code Online (Sandbox Code Playgroud)

另一个(也许更好)选项是让文件的第一行包含其中的记录数,然后您不必读取所有文件.

  • +1:我讨厌当人们回答我可以实际回答的问题之前,特别是当他们使用完全相同的代码时我会:) (4认同)

tva*_*son 11

读取每行,保持您目前所看到的行数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;
}
Run Code Online (Sandbox Code Playgroud)

基于用于从任意长链表中选择节点的C实现.

  • @GregS - 使用归纳推理.假设在第N步,每个元素具有1/n被选择的概率.对于N = 1,这很清楚.对于N = 2,第一个是在步骤1中选择的,并且在步骤2中具有1/2概率被替换,因此我们的假设成立.现在,在步骤中,根据我们的假设,每个前面的元素n + 1有1/n的机会被随机选择.概率1/n + 1我们选择替换它.显然,当前元素的选择概率为1/n + 1,但该元素是随机选择的,因此所有前面的元素都有1/n的概率被选中 (2认同)