我有一个“words”的文件,大小约为5.8 MB,其中包含560,000个单词。我正在使用它来从连接在一起的字符串中获取真实的单词。
E.g。 greenbananatruck 可以是这样的字符串。
我写这个函数的速度非常快。但我不能让它快于 0.5秒。我正在使用带有8核处理器,8GB RAM的服务器。实际上cpu不是问题,问题是RAM。我需要能够在多个实例中快速有效地完成此过程。
public function wordSplitReal( $str ){
$words = array_filter( $this->dict, function($word) use(&$str) {
$pos = strpos( $str, $word );
if ( $pos !== false ){
$str = substr_replace($str, "", $pos, strlen($word));
return true;
}
return false;
} );
return $words;
$words = array_filter( $this->dict, function($word) use(&$str) {
$pos = strpos( $str, $word );
if ( $pos !== false ){
$str = substr_replace($str, "", $pos, strlen($word));
return true;
}
return false;
} );
return $words;
这很简单,我实际上正在做的是“过滤”数组“dict”只有给定字符串中的单词。 (我对多个单词不感兴趣。) Dict从最长到最短的单词被预先排序。全部只有较低的字母。 这个函数是使用单例的更大类的一部分。
任何帮助都将不胜感激。
答案 0 :(得分:1)
数组对于这项工作来说是一个错误的工具,因为它们以线性时间访问(正如您所发现的那样,对于字典来说太慢了)。你可能想要一个特里;如果你搜索它们,有几个PHP实现。 (我没有任何PHP trie库的经验,因此我不推荐你。)
算法的大纲可能是:
While string is non-empty
For all prefixes of str in decreasing order:
If it is in trie:
Drop the prefix
Add it to the result array
Next iteration of outer loop
Return failure
Return result array
(算法不是很复杂,因为它没有实现回溯;留给读者的练习:p)