我有一组字符串和一组关键字。
实施例 字符串1:据报道,甲骨文和三星电子已经建立了新的合作关系,通过这种合作伙伴关系,他们将共同努力提供移动云服在上周四的会议上,甲骨文联合首席执行官Mark Hurd和三星电子移动主管Shin Jong-kyun
字符串2:这是一些随机字符串。
关键词:甲骨文,三星
该函数应返回String 1作为排名最高的字符串。我可以搜索每个字符串中的每个关键字,但是会花费太多时间,因为会有很多字符串和大量的关键字。
答案 0 :(得分:1)
创建一个数据结构,将任何字符串中出现的每个术语映射到它出现的所有字符串。
Map<String,List<Integer>> keyword2stringId;
如果一个字符串多次包含相同的关键字,您可以简单地将其多次添加到List
,或者 - 如果您愿意 - 使用稍微不同的地图,这样您也可以保持计数:
Map<String,List<Pair<Integer,Integer>>> keyword2pair; // pair = id + count
然后,对于每个关键字,您可以查找相关字符串并找到重叠率最高的字符串,例如:
// count the occurrences of all keywords in the different strings
int[] counts = new int[strings.length];
for (String keyword : keywords) {
for (Integer index : keyword2stringId.get(keyword)) {
if (index != null) {
counts[index]++;
}
}
}
// find the string that has the highest number of keywords
int maxCount = 0;
int maxIndex = -1;
for (int i = 0; i < counts.length; i++) {
if (counts[i] > maxCount) {
maxCount = counts[i];
maxIndex = i;
}
}
// return the highest ranked string or
// 'null' if no matching document was found
if (maxIndex == -1) {
return null;
} else {
return strings[maxIndex];
}
此方法的优点是您可以计算地图离线(即仅一次),然后一次又一次地用于不同的查询。
答案 1 :(得分:0)
看起来你应该试试一些搜索引擎或搜索库,例如Lucene或Solr
Lucene Core,我们的旗舰子项目,提供基于Java的索引 和搜索技术,以及拼写检查,点击突出显示和 高级分析/标记化功能。
Solr是一种流行的,超快速的开源企业搜索 基于Apache Lucene™构建的平台。
这两件事都支持你做你需要做的事情 - 搜索一些关键词并对它们进行排名。
答案 2 :(得分:0)
此程序不能 O(n)复杂度,也就是说,您必须使用每个关键字检查字符串的每个单词。
现在,您唯一可以做的就是一次性检查每个字符串:
public int getRank(String string, String[] keyword) {
int rank = 0;
for (String word : string.split(" "))
for (String key : keyword)
if (word.equals(key))
rank++;
return rank;
}
在这个简单的示例中,rank
每次在字符串中出现关键字时都会增加int
。然后为每个字符串填充一系列排名:
String[] strings = new String[]{"...", "...", "...", "...", ...};
String[] keyword = new String[]{"...", "...", "...", "...", ...};
int[] ranks = new int[stringsNumber];
for (int i = 0; i < stringsNumber; i++)
ranks[i] = getRank(strings[i], keyword);
答案 3 :(得分:0)
我相信您真正需要的是TF/IDF - 期限频率/反向文档频率。提供的链接应该为您提供所需的信息,或者@Mysterion指出,Lucene将为您提供此信息。您不一定需要部署完整的Lucene / Solr / ElasticSearch安装,您只需使用自己需要的类