有没有更有效的方法来评估字符串的包含性?

时间:2019-06-18 07:44:13

标签: java performance math

我必须执行这行cose数百万次,我想知道是否有一种方法可以对其进行优化(也许是预先计算的东西?)。

a.contains(b) || b.contains(a)

谢谢

编辑:contains方法执行的代码已经检查了a.length

public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
    byte first = str[0];
    int max = (valueCount - strCount);
    for (int i = fromIndex; i <= max; i++) {
        [...]
    }
    return -1;
}

1 个答案:

答案 0 :(得分:3)

据我了解的任务,您必须检查ab中每对a是否包含b,反之亦然(从大约3500万中话。要检查的对很多。

您应该能够通过预先计算一个单词包含哪些n-gram来缩小搜索范围:如果a包含某个n-gram,则b必须包含相同的n-gram b包含a。您可以例如预计算列表中每个单词包含的所有三字母组,同时计算包含给定三字母组合的所有单词,那么您只需查找这些词典中的单词,并通过一些设置操作即可获得一小部分候选词进行检查正确地

使用伪代码:

  • 选择n克大小(请参见下文)
  • 初始化Map<String, Set<String>> ngram_to_word
  • 第一次迭代:针对数据集中的每个单词a
    • 迭代a的所有n元语法(例如,使用某种滑动窗口)
    • 对于每个,在包含a的n-gram的单词集中添加ngrams_to_words
  • 第二次迭代:针对数据集中的每个单词a
    • 再次获取a包含的所有n元语法
    • 对于每一个,从ngrams_to_words中获取包含该n-gram的一组单词
    • 获取这些单词集的交集
    • 对于包含b所包含的所有n-gram(但可能以不同的顺序或数量)的交点中的每个单词a,请正确检查b是否包含{{ 1}}

取决于这些n-gram中字母的数量(例如,双字母组,trigram,...),它们在时间和空间上的预计算成本将更高,但效果也会更大。在最简单的情况下,您甚至可以预先计算哪些单词包含给定的字母(即“ 1-grams”);那应该很快并且已经相当可观地缩小了要检查的范围。当然,n-gram不应短于数据集中单词中最短的单词,但是您甚至可以使用两个长度的n-gram,例如使用两个地图aletter_to_words