Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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
Java 正在寻找执行字符串搜索的更快方法_Java_Perl_Optimization_Search - Fatal编程技术网

Java 正在寻找执行字符串搜索的更快方法

Java 正在寻找执行字符串搜索的更快方法,java,perl,optimization,search,Java,Perl,Optimization,Search,我必须识别大量URL(几百万行)是否属于特定类别。我有另一个列表,其中包含子字符串,如果URL中存在子字符串,则属于该类别。比如说,A类 要检查的子字符串列表中有大约10k个这样的子字符串。我所做的只是在子字符串文件中逐行查找匹配项,如果发现URL属于类别A。我在测试中发现这相当耗时 我不是计算机科学专业的学生,所以对优化算法不太了解。但有没有办法让这更快?只是简单的想法。编程语言不是一个大问题,但Java或Perl更可取 要匹配的子字符串列表不会有太大变化。然而,我将收到不同的URL列表,所以

我必须识别大量URL(几百万行)是否属于特定类别。我有另一个列表,其中包含子字符串,如果URL中存在子字符串,则属于该类别。比如说,A类

要检查的子字符串列表中有大约10k个这样的子字符串。我所做的只是在子字符串文件中逐行查找匹配项,如果发现URL属于类别A。我在测试中发现这相当耗时

我不是计算机科学专业的学生,所以对优化算法不太了解。但有没有办法让这更快?只是简单的想法。编程语言不是一个大问题,但Java或Perl更可取


要匹配的子字符串列表不会有太大变化。然而,我将收到不同的URL列表,所以每次我得到它时都必须运行它。瓶颈似乎是URL,因为它们可能变得很长。

您可以将子字符串压缩到共享相同前缀的类中。这将大大缩短时间


如果您通过每次迭代将字符串移位1来寻找匹配项,那么可以使用更好的算法(如正则表达式)大大提高速度

我建议使用古老的编程语言来完成这项任务,而不是使用编程语言。它使用fast,这应该足以容纳数百万条线路。

当然可以使用不同的方法来优化此功能。关于你的背景,我给你画一个简单的。假设子字符串列表不会经常更改

  • 从所有子字符串生成一个大型正则表达式
  • 编译该regexp,请参阅。例如,Java中的类模式。存储对该已编译正则表达式的引用
  • 使用相同的编译正则表达式匹配每个url
  • 是的,我针对您提出的问题用java实现了该算法,它显示出在朴素的实现(您正在做的事情)上有大约x180的一致改进。 虽然我会调整它们以获得更好的性能,但在线上有几种可用的实现。 请注意,解决方案的复杂性受单词长度(在您的例子中是URL)的限制,而不是子字符串的数量。此外,匹配平均只需要一次通过

    另外,我们过去在求职面试中经常向人们提出这个问题,所以有很多方法可以解决这个问题。我提供的是我们在生产代码中使用的解决方案,它(目前)胜过所有其他解决方案


    编辑:以前写了错误的算法名,修复了…

    Perl非常擅长优化正则表达式中的替换字符串的长列表(最大可达某个总编译正则表达式长度,在该长度下,它会还原为效率较低的机制)。 您应该能够构造一个正则表达式来匹配特定类别,如:

    $catAre = join( '|', map quotemeta, @catAstrings );
    $catAre = qr/$catAre/;
    

    对于实现通用字符串搜索算法的Java库,请参阅的答案。再加上并行化,您应该能够相当快地解析数百万个URL。这很容易做到;在进一步研究优化之前,您可能应该尝试一下,看看时间是否可以接受。

    我首先将其作为评论写下,但后来我意识到,我认为它更适合作为一个答案
    您可以使用一些信息检索系统(如Java)将URL作为文档进行索引。
    然后,在索引之后,您可以迭代查询,并搜索每个查询,结果将是匹配的URL。
    优点:
    *搜索不需要为每个查询迭代所有URl。
    *如果您以后需要子字符串/查询的交集或并集,库将为您提供此功能
    缺点:
    *索引将需要一段时间。。。
    *您可能需要在RAM/磁盘上为索引留出一些额外空间。


    我认为这是一种值得探索的方法,也许索引时花费的时间值得搜索。

    我以前在Perl中做过类似的事情,将~13k个关键字的列表与来自Twitter的传入数据流进行比较,以找到所有与这些关键字匹配的推文(以及每个关键字匹配的关键字)。粗略地说,代码如下所示:

    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...
    }
    
    请注意,这用于构建regex,它不是核心Perl发行版的一部分,因此如果要修改此代码,需要从CPAN安装if


    如果您使用的是perl 5.10或更高版本,还有一个“智能匹配”操作符(
    ~~
    ),它可以做类似的事情,而不需要任何额外的模块。

    我目前正在解决这个问题。我得出这样的结论:

    阿霍·科拉西克在制作树时会消耗更多内存。如果没有记忆的问题,那就好了。 但是看看这顶帽子,特里亚。它是hash和trie(tree)的组合。它将在某个级别生成一棵树,剩余的字符将形成一个哈希值,该值应标记在哈希表中


    关于更多的技术语言,我很抱歉。但我认为,如果您正在从URL列表中搜索特定的URL,则HAT-trie是更好的选择。(我已经建立了一个HAT-trie,它将消耗12MB来存储6ack的URL。)

    您可以使用一些信息检索系统(如Java中的Lucene)对URL进行索引,然后搜索字符串,索引将非常耗时,但它将为每个“查询”节省时间,而不必对整个列表进行迭代,1000万是什么,1000亿?是的,不管用哪种语言,那都需要一些时间。如果某物属于A类,是否意味着它们不能属于其他类别?如果是这样,您可以从大列表中删除分配给某个类别的所有内容。子字符串列表是常量。没有理由花费很长时间,请参见我的答案。列表的长度只会影响自动机在内存中的大小,甚至可能很小