Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中处理相对较大的数组?_Php_Arrays - Fatal编程技术网

如何在PHP中处理相对较大的数组?

如何在PHP中处理相对较大的数组?,php,arrays,Php,Arrays,我收集了超过5000个文本文件,有超过200000个单词。问题是,当我试图将整个集合合并到单个数组中以查找集合中的唯一单词时,没有显示输出(这是由于数组的大小非常大)。下面的代码适用于少量的集合,例如30个文件,但无法对非常大的集合进行操作。帮我解决这个问题。谢谢 <?php ini_set('memory_limit', '1024M'); $directory = "archive/"; $dir = opendir($directory); $file_array = array()

我收集了超过5000个文本文件,有超过200000个单词。问题是,当我试图将整个集合合并到单个数组中以查找集合中的唯一单词时,没有显示输出(这是由于数组的大小非常大)。下面的代码适用于少量的集合,例如30个文件,但无法对非常大的集合进行操作。帮我解决这个问题。谢谢

<?php
ini_set('memory_limit', '1024M');
$directory = "archive/";
$dir = opendir($directory);
$file_array = array(); 
while (($file = readdir($dir)) !== false) {
  $filename = $directory . $file;
  $type = filetype($filename);
  if ($type == 'file') {
    $contents = file_get_contents($filename);
    $text = preg_replace('/\s+/', ' ',  $contents);
    $text = preg_replace('/[^A-Za-z0-9\-\n ]/', '', $text);
    $text = explode(" ", $text);
    $text = array_map('strtolower', $text);
    $stopwords = array("a", "an", "and", "are", "as", "at", "be", "by", "for", "is", "to");
    $text = (array_diff($text,$stopwords));
    $file_array = array_merge($file_array,  $text);
  }
}
closedir($dir); 
$total_word_count = count($file_array);
$unique_array = array_unique($file_array);
$unique_word_count = count($unique_array);
echo "Total Words: " . $total_word_count."<br>";
echo "Unique Words: " . $unique_word_count;
?> 


文本文件的数据集可以在这里找到:

为什么要将所有数组合并到一个大的无用数组中


您可以使用该函数从数组中获取唯一值,然后将其与文件中的下一个数组连接起来,然后再次应用相同的函数。

不要将内存限制增加到高。这通常不是最好的解决方案

您应该逐行加载文件(在PHP中,当处理CSV格式时,这很容易),计算这一行(或一小部分行)并写入输出文件。这样,您就可以在占用少量内存的情况下处理大量的输入数据


无论如何,试着找到一种方法,将完整的输入分割成更小的块,即使不增加内存限制也可以处理。

另一种方法是将所有内容加载到db表中,然后让数据库服务器处理最多的内容


或者分块处理行,标记完成的行,或者将它们聚合到另一个表中。

不需要处理多个数组,只需构建一个数组,并用单词填充它,并在插入它们时对它们进行计数。这会更快,你甚至会有每个单词的计数

顺便说一下,您还需要将空字符串添加到stopwords列表中,或者调整您的逻辑以避免接受该字符串

<?php
$directory = "archive/";
$dir = opendir($directory);
$wordcounter = array();
while (($file = readdir($dir)) !== false) {
  if (filetype($directory . $file) == 'file') {
    $contents = file_get_contents($directory . $file);
    $text = preg_replace('/\s+/', ' ',  $contents);
    $text = preg_replace('/[^A-Za-z0-9\-\n ]/', '', $text);
    $text = explode(" ", $text);
    $text = array_map('strtolower', $text);
    foreach ($text as $word)
        if (!isset($wordcounter[$word]))
            $wordcounter[$word] = 1;
        else
            $wordcounter[$word]++;
  }
}
closedir($dir); 

$stopwords = array("", "a", "an", "and", "are", "as", "at", "be", "by", "for", "is", "to");
foreach($stopwords as $stopword)
    unset($wordcounter[$stopword]);

$total_word_count = array_sum($wordcounter);
$unique_word_count = count($wordcounter);
echo "Total Words: " . $total_word_count."<br>";
echo "Unique Words: " . $unique_word_count."<br>";

// bonus:
$max = max($wordcounter);
echo "Most used word is used $max times: " . implode(", ", array_keys($wordcounter, $max))."<br>";
?>


您是否尝试提高内存限制?我总共有2GB内存。您是否尝试使用XML文件或CSV?请更改方法。为什么要加载所有内容,然后循环所有内容?分块做有什么不对?@N.B.我不太擅长PHP:)。你能帮我把这段代码重新编写成一段一段地阅读吗?我建议你加上以下停止词:“the”,“of”,“in”。如果你这样做,你将有53'993个独特的单词被使用1'957'286次。“said”一词最多用39'973次。此脚本在我的计算机上运行不到8秒,处理了5000个文件(14.8MB)。我有一个包含28个停止字的列表。是否仍要将所述集合中的唯一字提取到单个数组中?您的代码正在提取它们的频率。@user3814982只需使用
array\u键($wordcounter)