对于本学期的最后一个项目,目标是在Song对象内的lyric String上运行特定短语的搜索,然后根据子字符串匹配的长度对结果进行排名。从文件中读取歌词并匹配该文件中的换行符。
例如,搜索“她爱你”会在示例匹配中返回这些:
披头士乐队:“...... 她爱你,是的,是的,是啊......”等级= 13个字符从上一个示例中可以看出,匹配可以跨越多行。
我有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。
我需要进行哪些更改才能清除误报和错误排名?
答案 0 :(得分:1)
我想补充一下jjinguy说的话:
基本上,在'其他'区块中,在找到与开头相匹配的第一个索引后,您还必须寻找可能的其他起点,如果找到另一个起点则重置开始
我会在歌曲中保留所有可能匹配的列表,最后使用排名最高的匹配。简单地重置起点可能无法捕捉到最佳等级的匹配。
也许这不是最好的方式,但问题仍然存在。