如何从文本文件中随机输出一行

4

我的文本文件格式如下:

这是第一行。
这是第二行。
这是第三行。

在文本文件中可能会有更多的行。如何使用php从文本文件中每次刷新随机选择一行进行输出。 感谢您的所有评论。


虽然这对于少量行可能有效,但如果您想要处理许多行的解决方案,请考虑使用数据库。 - user557846
2个回答

17

我们需要处理多大的文件?简单的方法是将整个文件作为字符串数组加载到内存中,然后从0到N之间选取一个随机数组索引并显示该行。

如果文件大小可能非常大,则必须实现某种类型的流式解决方案。

流式解决方案说明!

下面的解决方案将从相对较大的文件中产生一个均匀分布的随机行,并且每个文件具有可调整的最大行大小。

<?php
function rand_line($fileName, $maxLineLength = 4096) {
    $handle = @fopen($fileName, "r");
    if ($handle) {
        $random_line = null;
        $line = null;
        $count = 0;
        while (($line = fgets($handle, $maxLineLength)) !== false) {
            $count++;
            // P(1/$count) probability of picking current line as random line
            if(rand() % $count == 0) {
              $random_line = $line;
            }
        }
        if (!feof($handle)) {
            echo "Error: unexpected fgets() fail\n";
            fclose($handle);
            return null;
        } else {
            fclose($handle);
        }
        return $random_line;
    }
}

// usage
echo rand_line("myfile.txt");
?>

假设文件共有10行,则选取第X行的概率为:

  • P(1) = 1
  • P(2) = 1/2 * P(1)
  • P(3) = 2/3 * P(2)
  • P(N) = (N-1)/N * P(N-1) = 1/N

这将最终为我们提供一个均匀分布的随机行,而无需将整个文件读入内存。

希望这对你们有所帮助。


2
虽然你意识到了效率问题,但如果没有有效的答案,我实际上无法给你投票。 - Jon Egeland
是的,我曾经在面试中回答过类似的问题。非常有趣...如果你感兴趣,我可以发布完整的解决方案。 - Mohamed Nuur
如果您有解决方案并且它回答了问题,请发布它。否则,就让它保持不变... - Jon Egeland
请返回翻译后的文本:类似https://dev59.com/kXVC5IYBdhLWcg3woCrN?rq=1 - Mohamed Nuur

9
这种情况下的一个普遍好的方法是:
  1. 使用file()将行读入数组中
  2. 使用array_rand()随机显示一个数组值
你的代码可能如下所示:
$lines = file('my_file.txt');

echo $lines[array_rand($lines)];

3
指数级的内存和 CPU 使用量。我不建议使用它。 - cmc
你上了新闻啦!你是个明星 ;) - Funk Forty Niner
啊,抄袭。最真诚的恭维! - John Conde
是的,我的朋友;)我想给你带来一些业务。哦,我是那个+1的人-哈哈,不是“另一个人”。我喜欢扮演超人的日子。 - Funk Forty Niner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接