我正在使用java,并且有一个大型的(~15000)关键字(字符串)集合,并且我有一个定期包含这些关键字的文档(字符串)。
我想找到文档中每次使用关键字的索引,优先选择较长的关键字(字符数最多的关键字)。例如,如果我的关键字是“水”,“瓶子”,“喝水”和“水瓶”,而我的文件是“我从我的水瓶中喝了”,我希望得到以下结果:
2喝了
16个水瓶
我最初的尝试是使用trie,逐个字符地浏览文档,每当子字符串与关键字匹配时,记录初始索引。然而,一些关键字是较长关键字的前缀(例如,“水”和“水瓶”),并且代码永远不会找到更长的关键字,因为它会记录“水”的索引,然后重新开始。
如果重要,关键字可能包含小写字母,大写字母,空格,连字符和撇号(以及大写字母)。
因此,我们非常感谢您寻找最长关键字的任何帮助。感谢。
答案 0 :(得分:0)
如果关键字可以通过较小的关键字构建,那么您所使用的代码就是检查较长的关键字。请注意:我根本没有测试过,我想我已经把足够的工作放到这个问题上了!如果这有助于你不要忘记upvote + accept。
即。
import java.util.TreeSet;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.Iterator;
public class KeywordSearcher {
private TreeSet<String> ts;
public KeywordSearcher() {
ts = new TreeSet<String>(new Comparator<String>() {
// Sort all the keywords by length, largest first
public int compare(String arg0, String arg1) {
if(arg0.length() > arg1.length()) return -1;
if(arg0.length() == arg1.length()) return 0;
return 1;
}});
}
public void addKeyword(String s) {
ts.add(s);
}
private LinkedList<Integer> findKeyword(String document, String s) {
int start = 0;
int index;
LinkedList<Integer> indexes = new LinkedList<Integer>();
while(true) {
index = document.indexOf(s, start);
if (index == -1) break;
indexes.add(index);
start = index + s.length();
}
return indexes;
}
public HashMap<String, LinkedList<Integer>> findAllKeywords(String document) {
Iterator<String> is = ts.iterator();
HashMap<String, LinkedList<Integer>> allIndices = new HashMap<String, LinkedList<Integer>>();
while(is.hasNext()) {
String nextKeyword = is.next();
// See if we found a larger keyword, if we did already, skip this keyword
boolean foundIt = false;
for (String key : allIndices.keySet()) {
if(key.contains(nextKeyword)) {
foundIt = true;
break;
}
}
if (foundIt) continue;
// We didn't find the larger keyword, look for the smaller keyword
LinkedList<Integer> indexes = findKeyword(document, nextKeyword);
if (indexes.size() > 0) allIndices.put(nextKeyword, indexes);
}
return allIndices;
}
}
答案 1 :(得分:0)
如果我理解正确,如果您在文档中找到“水瓶”,则想跳过搜索“水”。这意味着您的关键字会出现某种树状结构。
我的建议是将您的关键字排列在这样的排序树上:
drank
water bottle
bottle
water
在您的代码中,您将首先搜索根目录中的术语(“喝水”和“水瓶”)。如果“水瓶”的匹配数量为零,那么您将导航到下一级别并搜索这些术语(“瓶子”和“水”)。
创建树需要一些工作。
但是使用这种树结构,你可以有多个复合词。
clean water bottle
clean bottle
clean
water bottle
bottle
water