【发布时间】:2011-05-08 12:43:46
【问题描述】:
对于本学期的最后一个项目,目标是在 Song 对象内的歌词字符串上运行特定短语的搜索,然后根据子字符串匹配的长度对结果进行排名。歌词是从文件中读取的,并与该文件中的换行符匹配。
例如,搜索“她爱你”会在示例匹配中返回以下内容:
披头士乐队:“...... 她爱你,是的,是的,是的......”排名= 13 个字符
Bonnie Raitt:“...她只是爱你 ...”排名= 18 个字符
埃尔维斯普雷斯利:“...你在问她是否爱我\r\n嗯,你不知道...” Rank= 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 对象来保存匹配的数组部分的歌曲、搜索短语、起点和终点。在 Rank 对象中是一种计算字符数并补偿空白以计算排名的方法。然后将其插入到 PriorityQueue 中,将从原始 matchSet 中提取前十个匹配项。
问题在于,这并不能防止误报,而且匹配排名可能会出现偏差。例如,Aerosmith 的 Beyond Beautiful 包含“……她爱我,她不爱你……”与我的过程,我将匹配“……她爱我她爱你 不是...”,所以我的排名不是 13,而是 27。
为了消除误报和错误排名,我需要进行哪些更改?
【问题讨论】:
-
基本上,在'otherwise'块中,找到第一个与起点匹配的索引后,您还必须寻找可能的其他起点,如果找到另一个起点,则重新设置起点。
-
我建议我们有homework.stackoverflow.com,我们只是在那里转发所有作业。 :)
-
我不介意,问题是过去一个月我标记为 -homework- 的每个帖子都已被编辑以删除标记。
-
@Neil: "The homework tag, like other so-called 'meta' tags, is now discouraged," 但是,@Jason,请(一如既往)继续(一如既往)关注general guidelines:说明任何特殊限制,展示您迄今为止尝试过的内容,并询问具体是什么让您感到困惑。你可以在文中提到这是作业,如果你认为这会给你更好的答案;但真正重要的是可能适用于您的独特限制,具体取决于您的学校(列表中的“特殊限制”)。
-
@The:就 SO 提出基本或家庭作业问题是可以接受的,我认为没有人真正反对这一点。
标签: java text-search