//--------------------------------------------------------------------- // static コンストラクタ // static KJ_dict() { #if DEBUG_DICTLOG KJ_dict.StartDebugLog(); KJ_dict.WriteDebugLog("KJ_dict static constructor"); #endif KJ_dict.HashAvailable = false; // デフォルトはHash未使用 KJ_dict.dictHash = new Hashtable(); // hash初期化 KJ_dict.dictCheckForwardHash = new Hashtable(); // hash初期化 KJ_dict.dictCheckFullHash = new Hashtable(); // hash初期化 }
// 辞書ファイルOpen // Arrayファイルを個別に指定する場合 static public void DictOpen(string yaml_master, string arrayfile) { yaml_master = "dict\\" + yaml_master; arrayfile = "dict\\" + arrayfile; dict_instance_w = new KJ_DictData(yaml_master, (arrayfile + ".w.ary")); dict_instance_c = new KJ_DictData(yaml_master, (arrayfile + ".c.ary")); #if DEBUG_DICTLOG KJ_dict.WriteDebugLog("## DictOpen ##"); KJ_dict.WriteDebugLog("yaml_master=" + yaml_master + ", arrayfile=" + arrayfile); #endif }
//--------------------------------------------------------------------- // 条件にマッチする辞書の登録語の最初のグループを調べる private long bsearch_top(SearchType searchtype, String search_word) { if (search_word.Length == 0) { return(-1); // 該当語なし } // とりあえずマッチする1個を調べる long index = bsearch_match_one(searchtype, search_word); if (index == -1) { #if DEBUG_DICTLOG KJ_dict.WriteDebugLog("■Cannot found [" + search_word + "]"); #endif return(index); // 該当語なし } // indexから前方にマッチする間さかのぼる int cnt = 0; // カウンタ while (true) { if (cnt > 100) { // 100以上は さかのぼらない // 最大100個しか返さないので無駄な検索はしない break; } cnt++; // indexは一致している。その1つ前を調べる。 long check = index - 1; if (check < 0) { break; // indexは0が最小。 } String word = KJ_SuffixArray.GetWord(this.dict_fs, this.array_reader, check); if (this.dictword.Compare(searchtype, search_word, word)) { // 1つ前も一致したならさらにさかのぼる index = check; } else { break; // 一致しないなら終了 } } return(index); }
//--------------------------------------------------------------------- // 辞書引きのメインのサーチメソッド。 public SearchResult Search(SearchType searchtype, String search_word) { SearchResult result = new SearchResult(); #if DEBUG_DICTLOG KJ_dict.WriteDebugLog ("------------------------------------------------------------"); KJ_dict.WriteDebugLog("Search Start"); #endif // 条件にマッチするarrayの要素の先頭番号を調べる long match_top = bsearch_top(searchtype, search_word); #if DEBUG_DICTLOG KJ_dict.WriteDebugLog("Search End"); #endif if (match_top == -1) { result.return_code = -1; result.documents = new ArrayList(); return(result); // 検索ができなかった } // マッチした先頭から順に取り出し,resultにつなぐ result.return_code = 0; result.documents = new ArrayList(); long index = match_top; int cnt = 0; while (true) { // suffix arrayのindex番目の語を取り出す String word = KJ_SuffixArray.GetWord(this.dict_fs, this.array_reader, index); // 取り出した語は検索条件にマッチするか? if (this.dictword.Compare(searchtype, search_word, word)) { // マッチするならその語を含むドキュメント全体を取り出す long dict_pointer = KJ_SuffixArray.GetSeekPointer(this.array_reader, index); DocumentData docdata = KJ_yaml.GetBlock(this.dict_fs, dict_pointer); // 既出でないならresultに追加 if (!result.IsExist(docdata)) { // 絞込みのフィルタ if (this.dictFilter(docdata)) { result.documents.Add(docdata); // 戻り値として追加 } else { // フィルタにマッチしないなら返さない cnt--; // adhocだが、先に1減じておく } } else { // 既出ならcntしない cnt--; // adhocだが、先に1減じておく } } else { break; // 一致しなければ終了 } index++; // suffix arrayの次へ if (index > array_index_max) { break; } // 検索語の数をカウント cnt++; if (cnt > 100) { result.return_code = 1; // 100個を越えたら中断 break; } } // 返すべき値がなければ戻り値を -1に if (cnt == 0) { result.return_code = -1; } // 検索結果を返す return(result); }
//--------------------------------------------------------------------- // とりあえずマッチする1個を調べる (バイナリサーチ) // マッチする一群の先頭とは限らない // // もし見つかったらSuffix Arrayのindex pointを返す // -1 : 見つからなかった // public long bsearch_match_one(SearchType searchtype, string search_word) { long low; long high; high = array_index_max; low = 0; long index; #if DEBUG_DICTLOG KJ_dict.WriteDebugLog("index,low,high"); #endif // 最初の検索index設定 index = (high - low) / 2 + low; // 5/2-->2 (.5切捨て) while (true) { String word = KJ_SuffixArray.GetWord(this.dict_fs, this.array_reader, index); #if DEBUG_DICTLOG KJ_dict.WriteDebugLog(index + "," + low + "," + high); KJ_dict.WriteDebugLog(" word=" + word + "(" + index + ")"); String wordTemp; wordTemp = KJ_SuffixArray.GetWord(this.dict_fs, this.array_reader, low); KJ_dict.WriteDebugLog(" low =" + wordTemp + "(" + low + ")"); wordTemp = KJ_SuffixArray.GetWord(this.dict_fs, this.array_reader, high); KJ_dict.WriteDebugLog(" high=" + wordTemp + "(" + high + ")"); #endif if (this.dictword.Compare(searchtype, search_word, word)) { // 見つかったので抜ける #if DEBUG_DICTLOG KJ_dict.WriteDebugLog("■Found [" + search_word + "] (index=" + index + " word=" + word + ")"); #endif break; } if (low == index) { if (high == (low + 1)) { // もしlowとhighが1しか違わないなら // lowはチェック済みなのでhighをチェックすればいい index = high; // 次の検索index再設定 continue; } else { return(-1); // マッチせず } } if (high == index) { return(-1); // マッチせず } string word_no_space = word.Replace(" ", ""); // 2005.08.19 string search_word_no_space = search_word.Replace(" ", ""); // 2005.08.19 if (String.CompareOrdinal(word_no_space, search_word_no_space) < 0) // 2005.08.19 // if(String.CompareOrdinal(word, search_word) < 0 ) // 2005.08.19 { low = index; // もしlowとhighが1しか違わないなら // lowはチェック済みなのでhighをチェックすればいい if (high == (low + 1)) { index = high; // 次の検索index再設定 continue; } } else { high = index; } index = (high - low) / 2 + low; // 次の検索index再設定 } return(index); }