【问题标题】:Read random line from a file? c#从文件中读取随机行? C#
【发布时间】:2010-09-19 13:52:31
【问题描述】:

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

名字姓氏

我需要从文件中随机挑选一个名字和列表名。

【问题讨论】:

  • 请发布您现在拥有的...

标签: c# .net file


【解决方案1】:
string[] lines = File.ReadAllLines(...); //i hope that the file is not too big
Random rand = new Random();
return lines[rand.Next(lines.Length)];

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

【讨论】:

  • +1:我讨厌别人回答我实际上可以回答的问题,尤其是当他们使用与我完全相同的代码时:)
  • 谢谢,我刚刚想通了。但你的方式似乎更好。
  • 只要文件比较小就可以。我提供了一种替代方法,让您不必将整个文件保存在内存中。
  • @tvanfosson:如果文件非常大(通过在第一行添加记录数),第二个版本也可以工作,并且它对您的解决方案的优势(从数学角度来看我真的很喜欢)是平均只读取文件的一半(每次只在内存中读取一行)。
  • +1 表示“文件的第一行包含记录数”部分。
【解决方案2】:

阅读每一行,记下你目前看到的行数 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 implementation 从任意长的链表中选择一个节点。

【讨论】:

  • 数学对我来说是错误的。选择第一行的概率不是1/n吗!到最后?
  • 这里的数学很好:)
  • @Itay:如果你相信 cmets:我不相信。但是,我以前也被概率愚弄过。
  • @Itay:啊,我想我现在知道了。在步骤 n 中,您以 (n-1)/n 的概率保留先前的选择。并且通过归纳,先前选择的概率是 1/(n-1),所以乘以得到 1/n。聪明。
  • @GregS - 使用归纳推理。假设在第 N 步,每个元素都有 1/n 的概率被选中。对于 N = 1,这很清楚。对于 N = 2,第一个是在步骤 1 中选择的,并且在步骤 2 中被替换的概率为 1/2,因此我们的假设成立。现在在步骤,根据我们的假设,n+1 个前面的元素有 1/n 的机会被随机选择。我们以 1/n+1 的概率选择替换它。显然,当前元素有 1/n+1 的概率被选中,但该元素是随机选择的,所以所有前面的元素都有 1/n 的概率被选中
猜你喜欢
  • 2017-02-28
  • 2015-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多