java - 是否有更有效的方法来评估字符串的包含情况?
问题描述
我必须执行这行 cose 几百万次,我想知道是否有办法对其进行优化(可能是预先计算一些东西?)。
a.contains(b) || b.contains(a)
谢谢
编辑: contains 方法执行的代码已经检查 a.length < b.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;
}
解决方案
据我了解这项任务,您必须检查每对是否a
包含b
或反之亦然,a
并且b
来自一组大约 3500 万个单词。有很多对要检查。
您应该能够通过预先计算一个单词包含哪些 n-gram 来大大缩小搜索范围:如果a
包含一些 n-gram,则b
必须包含相同的 n-gram if b
contains a
。例如,您可以预先计算列表中每个单词包含的所有三元组,同时预计算包含给定三元组的所有单词,然后您只需查找这些字典中的单词,并通过一些集合操作得到一小组考生要正确检查。
在伪代码中:
- 选择 n-gram 的大小(见下文)
- 初始化一个
Map<String, Set<String>> ngram_to_word
a
第一次迭代:对于数据集中 的每个单词- 迭代所有的 n-gram(例如使用某种滑动窗口)
a
- 对于每一个,添加
a
到包含这些 n-gram 的单词集合中ngrams_to_words
- 迭代所有的 n-gram(例如使用某种滑动窗口)
a
第二次迭代:对于数据集中 的每个单词- 再次获得所有 n-gram
a
包含 - 对于其中的每一个,从
ngrams_to_words
- 得到这些词集的交集
b
对于包含所有 n-gram 的交集中的每个单词a
(但可能以不同的顺序或数量),正确检查是否b
包含a
- 再次获得所有 n-gram
根据这些 n-gram 中的字母数量(例如 bigrams、trigrams...),它们在时间和空间上的预计算成本会更高,但效果也会更大。在最简单的情况下,您甚至可以预先计算哪些单词包含给定字母(即“1-gram”);那应该很快并且已经相当缩小了要检查的单词。当然,n-gram 不应该比数据集中最短的单词短,但是你甚至可以使用两个长度的 n-gram,例如使用两个 mapletter_to_words
和trigrams_to_words
。
推荐阅读
- pandas - 如何处理并行返回大结果的小数据帧
- python - 如果有人特别发送消息,如何让不和谐机器人发送消息
- javascript - JS如何使用“this”关键字查找对象的名称?
- html - 为什么我在圆圈中的 SVG 图标不可见?
- python - Pandas 计算和数据集读取
- python - kivy.core.window._window_sdl2._WindowSDL2Storage.show_keyboard 中的文件“kivy/core/window/_window_sdl2.pyx”,第 582 行
- node.js - 基于角色的访问控制,其中用户可以在多个场景中拥有多个角色
- r - ifelse 返回尝试在 R 中复制“S4”类型的对象错误
- c# - 使用字符串将 dbcontext 添加到服务
- sql - SQL 查询,连接两个表,ORDER BY 不起作用