查找包含另一个字符串的字符串部分,可能有插入的单词

时间:2010-11-11 14:59:51

标签: java text-search

对于本学期的最后一个项目,目标是在Song对象内的lyric String上运行特定短语的搜索,然后根据子字符串匹配的长度对结果进行排名。从文件中读取歌词并匹配该文件中的换行符。

例如,搜索“她爱你”会在示例匹配中返回这些:

披头士乐队:“...... 她爱你,是的,是的,是啊......”等级= 13个字符
Bonnie Raitt:“...... 只是爱你 ......”等级= 18个字符
埃尔维斯普雷斯利:“......你问她是否喜欢 我\ r \ n很好,不知道......”等级= 23个字符

从上一个示例中可以看出,匹配可以跨越多行。

我有TreeMap<String, TreeSet<Song>>中的所有歌曲,因此我获得了与查询中第一个单词匹配的所有歌曲。我遇到的困难是在字符串中搜索匹配项,因为在这种情况下正则表达式不起作用。

构建Song对象时,我将歌词转储到Set中以运行搜索单个单词,为此,我使用String.split("[^a-zA-Z}")分隔单个单词并清除标点符号。所以我想在那个阵列上运行我的搜索。我正在使用的过程如下:

break up the query into a String array
  for each Song in the set
    if (song.lyrics.contains(query)
      great, break loop to next song

    otherwise
      int queryCounter=0;
      find first index point in String array that matches query[queryCounter]
        using that as the start point, iterate through the String array for matches

当迭代完成时,会创建一个Rank对象来保存匹配的数组部分的Song,搜索短语,起始点和结束点。在Rank对象中是一种计算字符数并补偿空格来计算排名的方法。然后将其插入PriorityQueue,其中前十个匹配将从原始matchSet中拉出。

问题在于,这并不能防止误报,并且匹配等级可能会出现偏差。例如,Aerosmith的Beyond Beautiful包含“......她爱我,她不爱你......”通过我的过程,我将匹配“... 她喜欢我爱她你< / strong> not ...“,所以不是等级13,我的等级是27。

我需要进行哪些更改才能清除误报和错误排名?

1 个答案:

答案 0 :(得分:1)

我想补充一下jjinguy说的话:

  

基本上,在'其他'区块中,在找到与开头相匹配的第一个索引后,您还必须寻找可能的其他起点,如果找到另一个起点则重置开始

我会在歌曲中保留所有可能匹配的列表,最后使用排名最高的匹配。简单地重置起点可能无法捕捉到最佳等级的匹配。

也许这不是最好的方式,但问题仍然存在。