如何解决寻找执行字符串搜索的更快方法
| 我必须认识到一大类URL(几百万行)是否属于特定类别。我还有另一个列表,其中包含子字符串,如果URL中存在子字符串,则属于该类别。说,类别A。 要检查的子字符串列表大约有1万个这样的子字符串。我所做的只是在子字符串文件中逐行查找匹配项,如果发现该URL属于CategoryA。我在测试中发现这很耗时。 我不是计算机科学专业的学生,所以对优化算法没有太多的了解。但是有没有办法使它更快呢?只是简单的想法。编程语言不是大问题,但是Java或Perl是更可取的。 要匹配的子字符串列表不会有太大变化。但是,我将收到不同的URL列表,因此每次获得它时都必须运行它。 URL似乎是瓶颈,因为它们可能变得很长。解决方法
是的,我针对您提出的问题在Java中实现了Aho-Corasick算法算法,它在朴素的实现(您正在做的事情)上显示出约x180的一致改进。
尽管我会调整它们以获得更好的性能,但在线上有几种实现方式。
请注意,解决方案的复杂性受单词长度(在您的情况下为URL)的限制,而不是子字符串的数目。此外,平均只需要通过一次即可进行匹配。
附注-我们过去经常在工作面试中向人们提出这个问题,因此有很多解决方法。我提供的是我们在生产代码中使用的一种,(目前)优于所有其他解决方案。
编辑:以前写错了算法名称,已修复...
,Perl非常擅长优化正则表达式中的替换字符串的长列表(达到一定的总编译正则表达式长度,在这种情况下它会转换为效率较低的机制)。
您应该能够构造一个正则表达式来匹配某个类别,例如:
$catAre = join( \'|\',map quotemeta,@catAstrings );
$catAre = qr/$catAre/;
,当然可以使用不同的方法来对此进行优化。关于您的背景,我将简单介绍一下。假设子字符串列表不会经常更改。
从所有子字符串生成一个巨大的正则表达式。
编译该正则表达式,请参见。例如Java中的类Pattern。将折射率存储到该已编译的正则表达式中。
使用相同的已编译正则表达式来匹配每个url。
,我建议使用古老的Grep代替此任务使用编程语言。它使用快速的Boyer-Moore字符串搜索算法,对于几百万行来说应该足够了。
,我之前在Perl中已经做过这种事情,将〜13k关键字列表与来自Twitter的传入数据流进行比较,以查找与这些关键字中的任何一个匹配的所有tweet(以及每个匹配的关键字)。粗略地说,代码如下所示:
use Regexp::Assemble;
my $ra = Regexp::Assemble->new;
$ra->add(@keywords);
my $regex = $ra->re;
for my $tweet (@tweets) {
my @matches = $tweet =~ /$regex/g;
# do whatever with @matches...
}
请注意,这使用Regexp :: Assemble来构建正则表达式,它不是Perl核心发行版的一部分,因此,如果要从CPAN安装该代码,则需要进行安装。
如果您使用的是Perl 5.10或更高版本,则还有“智能匹配”运算符(~~
),它可以执行类似的操作而无需任何其他模块。
,您可以将子字符串压缩为共享相同前缀的类。这将大大减少时间。
如果您要通过每次迭代将字符串移位1来寻找匹配项,则可以使用更好的算法(与正则表达式一样)大大提高速度。
,对于实现常见字符串搜索算法的Java库,请参见https://stackoverflow.com/questions/5564610/fast-alernative-for-stringindexofstring-str的答案。加上并行化,您应该能够相当快地解析数百万个URL。这很容易做到;您可能应该尝试一下,看看时间是否可以接受,然后再进一步进行优化。
,我首先将其写为评论,但后来我意识到,我认为它更适合作为答案
您可以使用某些信息检索系统(例如Java中的Apache Lucene)并将其用作文档的URL索引。
然后,在建立索引之后-您可以遍历查询并搜索每个查询,结果将是匹配的URL。
优点:
*搜索将不需要遍历每个查询的所有URl。
*如果以后需要子串/查询的交集或并集-库为您提供此功能
缺点:
*索引编制将需要一段时间...
*您可能需要在RAM /磁盘上有一些额外的空间用于索引。
我认为这是一种值得探索的方法,也许索引时所花费的时间值得进行搜索。
,我目前正在解决这个问题。我得出这个结论:
Aho-corasick在制作树时会消耗更多的内存。如果没有记忆,那就比它好。
但是,请看一下HAT Trie。它是哈希和特里(树)的组合。它将在某种程度上构成一棵树,其余字符将构成一个哈希值,应在哈希表中进行标记。
抱歉,我们的技术语言更多。但是我认为,如果您要从URL列表中搜索特定的URL,则HAT trie是更好的选择。 (我已经形成了一个HAT trie,它将占用12MB的空间来存储6个URL的缺失。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。