接尾辞配列
WEB+DB Magazineを読んでいます。
書籍内記事にて言及されていた接尾辞配列の理解のため、記載されている動きをC#で組んでみました。
圧縮接尾辞配列は理解できていません…
(理解を目的としているのでString#SubStringを多用していたりArray#BinarySearchを使ってなかったりといった点はとりあえず置いてます)
using System; using System.Collections.Generic; namespace ConsoleApplication5 { class Program { static void Main() { string text = @" 『はてなダイアリー』の容量は無制限だから、毎日たくさんブログを書いても全く問題なし! 広告が勝手に表示されないので、思う存分デザインを楽しめます。 ブログの見た目を決めるデザインテーマは300以上。 自分のブログを本にすることも可能です。"; string[] words = new string[] { "はてな", "容量", "勝手に表示されない", "30", "ふがふが" }; List<int> suffixIndexList = MakeSAList(text); List<string> results = SearchWords(words, text, suffixIndexList); results.ForEach(Console.WriteLine); Pause(); } static List<int> MakeSAList(string text) { List<int> result = new List<int>(); for (int i = 0; i < LastIndex(text); i++) result.Add(i); result.Sort(delegate(int x, int y) { string xText = GetText(text, x); string yText = GetText(text, y); return xText.CompareTo(yText); }); return result; } static List<string> SearchWords(string[] words, string text, List<int> suffixIndexList) { List<string> results = new List<string>(); foreach (string word in words) { int i = Search(word, text, suffixIndexList, 0 , LastIndex(text)); string result = (i > -1) ? string.Format("{0} : {1}〜", i, GetText(text, i).Substring(0, 5)) : "(NotFound!)"; results.Add( string.Format("@ {0} : {1}", word, result)); } return results; } static void Pause() { Console.ReadLine(); } static int Search(string word, string text, List<int> suffixIndexList, int head, int tail) { if (head > tail) return -1; int pibot = (head + tail) / 2; string result = GetText(text, suffixIndexList[pibot]); if (result.StartsWith(word)) return suffixIndexList[pibot]; else if (word.CompareTo(result) < 0) return Search(word, text, suffixIndexList, head, pibot - 1); else return Search(word, text, suffixIndexList, pibot + 1, tail); } static string GetText(string text, int i) { return text.Substring(LastIndex(text) - i); } static int LastIndex(string text) { return text.Length - 1; } } }
実行結果。
@ はてな : 121 : はてなダイ〜 @ 容量 : 111 : 容量は無制〜 @ 勝手に表示されない : 74 : 勝手に表示〜 @ 30 : 26 : 300以上〜 @ ふがふが : (NotFound!)