根据提供的关键字排列文本

时间:2015-01-28 11:44:49

标签: java

我有一组字符串和一组关键字。

实施例 字符串1:据报道,甲骨文和三星电子已经建立了新的合作关系,通过这种合作伙伴关系,他们将共同努力提供移动云服在上周四的会议上,甲骨文联合首席执行官Mark Hurd和三星电子移动主管Shin Jong-kyun

字符串2:这是一些随机字符串。

关键词:甲骨文,三星

该函数应返回String 1作为排名最高的字符串。我可以搜索每个字符串中的每个关键字,但是会花费太多时间,因为会有很多字符串和大量的关键字。

4 个答案:

答案 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)

看起来你应该试试一些搜索引擎或搜索库,例如LuceneSolr

  

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安装,您只需使用自己需要的类