【问题标题】:Get nth number from a string从字符串中获取第 n 个数字
【发布时间】:2014-12-31 05:41:05
【问题描述】:

我有一个非常大的文件,只有一行。它包含大约 260 万个数字。该文件约为 15 mb。

我的目标是在这个单行字符串中找到第 n 个数字。

我试图将文件读入一个字符串(记住它是单行文件)。然后我将字符串分解成一个内存不足的数组。 (允许内存大小268435456字节用尽(尝试分配71字节)

我做得对吗?还是有其他更简单的方法可以在一个非常大的字符串中找到第 n 个值?

$file = file_get_contents ('a.txt', true);
$array = explode(" ", $file, -1);
echo $array[$nth];

【问题讨论】:

  • 是的。抱歉,在 PHP 中。
  • 我们需要更多地了解您的文件。当您说 260 万个数字时,您显然不是在谈论 260 万个数字,否则文件将是 2.6 mb,而不是 15mb。因此,请向我们展示您实际使用的示例。
  • 自从 OP 爆炸字符串以来,我们谈论的是空格分隔的数字。我猜。
  • 您始终可以按较小的片段分析文件,例如一次一 MB。
  • 文件是这样的:122 322 3222 2111 852 211 -233 358 0 12 ....,空格分隔。

标签: php string memory explode


【解决方案1】:

创建一个计数器变量;使用fopen 读取文件并在一段时间内使用feoffgets 循环它(使用所需的缓冲区大小);在循环中,检查您刚刚阅读的位中有多少空格(我假设您的条目用空格分隔,可以是逗号或其他);最后增加计数器并继续直到你到达你想要的部分(在 n 空格数之后,你有你正在寻找的 [n+1]th 条目)。

我包含了一些经过测试(带有 16 MB 文件)的概念验证代码。我不知道是否有更好的方法来做到这一点;这是我想到的唯一一个并且它有效。 memory_get_usage 报告内存使用量约为 8 kb。

<?php

$counter;
$nth = 49959;
$handle = @fopen('numbers.txt', 'r'); // File containing numbers from 1 to 2130829, size ~16 MB.

if ($handle) {
    while (($buffer = fgets($handle, 128)) !== false) {
        $spaces = substr_count($buffer, ' ');

        if ($counter + $spaces > $nth) {
            $numbers = explode(' ', $buffer);
            $key = $nth - $counter;
            echo $numbers[$key]; // print '49959'
            exit;   
        }
        else {
            $counter += $spaces;
        }
    }

    if (!feof($handle)) {
        echo "Error: unexpected fgets() fail\n";
    }

    fclose($handle);
}

?>

【讨论】:

  • 谢谢。如上所述,数字都是不同的大小,例如 0、122、-233 等。它们是用空格分隔的。如何使用 fgets 一次读取一个数字(不是数字)?
  • 你不能,但这没关系,因为你只是在循环,直到找到你的号码。我写了一个概念验证代码,并对其进行了测试。我将其包含在答案中。
  • 谢谢你,熵。我认为这行得通!但我也想知道我是否将这些数字放在 ID 的 mysql 表中,数字作为唯一的两列。所以每次我需要查找的时候,我都可以通过 ID 来查找它。每次都会比 fgets 快吗?
  • 是的,这样会更好。这取决于您是否已经设置了 MySQL 的基础架构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-24
  • 2015-12-14
  • 2022-06-13
  • 1970-01-01
  • 2018-02-19
  • 2015-02-08
相关资源
最近更新 更多