学期の最後のプロジェクトの目標は、Songオブジェクト内の歌詞文字列で特定のフレーズの検索を実行し、部分文字列の一致の長さに基づいて結果をランク付けすることです。歌詞はファイルから読み取られ、そのファイルの改行と一致します。
たとえば、「彼女はあなたを愛しています」を検索すると、サンプルの一致でこれらが返されます。
ビートルズ:「...彼女はあなたを愛しています、ええ、ええ、ええ...」ランク= 13文字
ボニー・レイット:「...彼女はあなたを愛しています...」ランク= 18文字
エルビス・プレスリー:「...あなたは彼女が私を愛しているかどうか尋ねています\r\ nまあ、あなたは知りません..."ランク=23文字
最後の例からわかるように、一致は複数の行にまたがることができます。
にすべての曲があるTreeMap<String, TreeSet<Song>>
ので、クエリの最初の単語に一致するすべての曲を取得します。この状況では正規表現が機能しないため、文字列で一致するものを検索するのが困難です。
Songオブジェクトが作成されたら、歌詞をSetにダンプして、1つの単語の検索を実行しました。これを行うには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オブジェクトが作成されます。ランクオブジェクトには、文字数をカウントし、空白を補正してランクを計算するメソッドがあります。次に、これはPriorityQueueに挿入され、上位10件の一致が元のmatchSetから取得されます。
問題は、これによって誤検知が防止されず、一致ランクが歪む可能性があることです。たとえば、AerosmithのBeyond Beautifulには、「...彼女は私を愛している彼女はあなたを愛していない...」が含まれているので、私のプロセスでは、「...彼女は私を愛している彼女はあなたを愛していない...」と一致します。 13のランクは27になります。
誤検知や誤ったランキングを取り除くには、どのような変更が必要ですか?