Esempio n. 1
0
        //-------------------------------------------------------
        //  分割なし完全一致の語
        static public WordTable Scan(WordChain wChain, WordTable wTable)
        {
            if (wTable.IsTranslated())
            {
                return(wTable);  // 変換済みなら何もしない
            }


            // 翻訳しなくていい文字は抜ける
            if (!wTable.IsWord() ||     // 空白や制御文字
                wTable.IsDigit() ||
                wTable.IsOther())       // 記号
            {
                return(wTable);
            }


            // 助詞なら抜ける
            if (wTable.posCategory == PosCategory.PP)
            {
                return(wTable);
            }


            // 独立した1文字の語は辞書より先に検索   (単独の이など)
            if (wTable.word.Length == 1)
            {
                CheckOneWord(wTable);
                if (wTable.transWord != "")
                {
                    return(wTable);    // match
                }
            }


            // 全体で完全一致で検索
            SearchResult sResult = KJ_dict.SearchFull(wTable.word);

            if (sResult != null)
            {
                wTable.SetResult(sResult);
                return(wTable);    // 完全一致で見つかった
            }


            // 4文字語の調査 (部分分割後は使わない)
            WordChain wc = Check4Chars(wTable);

            if (wc != null)
            {
                wChain.Swap(wTable, wc);
                return(wc.Tail);
            }



            return(wTable);
        }
Esempio n. 2
0
        //-------------------------------------------------------
        // 語のchainを先頭から舐め、助詞(Postpositional Particle)を分解する。
        static private WordTable ScanPPJp(WordChain wChain, WordTable wTable)
        {
            // 語を舐め、助詞を分解する。

            if (wTable.IsTranslated() || wTable.IsDigit())
            {
                // 翻訳済み または 数字ならなにもしない。
                return(wTable);
            }

            // J-->K方向の場合、ハングルは
            // 前の語に依存するので訳語(ハングル)の設定は別途。
            // 助詞である事の確定だけ試みる

            // 分離されたひらがなの助詞判定だけ
            PosCategory pp = CheckPos_Hira(wTable.word);

            if (PosCategory.PP == pp)
            {
                wTable.posCategory = pp;
            }

            // 漢字+ひらがなの形での助詞分離
            if (wTable.charCategory == CharCategory.KanHira)
            {
                WordChain resultChain = DivideJapanesePP(wTable);
                if (resultChain != null)
                {
                    wChain.Swap(wTable, resultChain);
                    // 前の語は未翻訳なのでそれを返す
                    wTable = resultChain.Head;
                }
            }


            return(wTable);
        }
Esempio n. 3
0
        //-------------------------------------------------------
        // 語のchainを先頭から舐め、助数詞・冠数詞を解析する。
        static public WordTable Scan(WordChain wChain, WordTable wTable)
        {
            if (wTable.IsTranslated())
            {
                return(wTable);  // 変換済みなら何もしない
            }

            WordTable next = wTable.NextWord();  // 次の有効な語を返す。(空白skip)

            // 前後を数字(Digit)に挟まれる場合
            if ((wTable.prev != null && wTable.prev.IsDigit()) &&
                (next != null && next.IsDigit()))
            {
                string transword = KJ_Filter.SearchNumConnecting(wTable.word);
                if (transword != "")
                {
                    wTable.transWord   = transword;
                    wTable.posCategory = PosCategory.Numerative;
                    wTable.Cost        = 1;
                    return(wTable);
                }
            }

            // 1つ前のWordTableは数字(Digit)の場合
            // または数詞(Numeral)である場合
            if ((wTable.prev != null && wTable.prev.IsDigit()) ||      // 800억 の 억
                (wTable.PrevWord() != null &&
                 wTable.PrevWord().posCategory == PosCategory.Numeral) // 800억원 --> 800+억+원の원
//                 160억 개의 のように空白をはさむ事があるので空白skipで前の語を調べる
                )
            {
                WordChain dividedChain = DivideCountable(wTable);

                if (dividedChain != null)
                {
                    // 助数詞であった

                    // devidedChainは 助数詞+語のチェーン。wTableと入れ替える
                    //   (+語はない場合もある)
                    wChain.Swap(wTable, dividedChain);

                    // 処理済みTable変更
                    wTable = dividedChain.Head;
                }
            }
            else
            {
                // 次の語が数字である場合 (冠数詞)  NumerativePrefix
                //   ★前数字と違い、空白はさんでも許す  (약 90만  or  약90만)
                if (next != null && next.IsDigit())
                {
                    string transword = KJ_Filter.SearchPreNum(wTable.word);
//                    string transword = CheckPreNum(wTable);
                    if (transword != "")
                    {
                        wTable.transWord   = transword;
                        wTable.posCategory = PosCategory.NumerativePrefix;
                        // ちょっと違うか。あとで
                        wTable.Cost = 1;
                    }
                }
            }

            return(wTable);
        }
Esempio n. 4
0
        //--------------------------------------------------------------------
        // 語の変換   (語の分解あり)
        //   語分解で翻訳済み末尾がずれることがあるのでWordTableを返す
        //           ABCDEF という語に対し、
        //              ABCDE + F
        //              ABCD  + EF
        //              ABC   + DEF
        //               :       :
        //   と調べていき、最小コストの訳語がとれる分割を採用する
        //
        static public WordChain  WordPartProc(WordTable wt)
        {
            SearchResult sResult;
            String       str = wt.word;


            if (wt == null)
            {
                return(null);
            }
            if (wt.word != null && wt.word.Length == 1)    // 1文字検索はしない
            {
                return(null);
            }

            if (wt.IsTranslated() || wt.IsDigit())
            {
                return(null); // 翻訳済みまたは 数字なら 何もしない
            }

            #if DEBUG_LOG
            KJ_Analyzer.WriteDebugLog("WordPartProc:" + wt.word);
            #endif


            // 再起に備え,まず完全一致で検索
            sResult = KJ_dict.SearchFull(str);
            if (sResult != null)
            {
                wt.SetResult(sResult); // 全体でmatch
                WordChain wc = new WordChain(wt);
                return(wc);
            }

            // 部分語の2文字は分割しない
            if (wt.word != null &&
                wt.word.Length == 2 &&
                wt.divided != Divided.Non)
            {
                return(null);
            }

            // 3文字の「ハングルまたは漢字」なら特別チェック
            if (wt.word != null && wt.word.Length == 3 &&
                wt.divided != Divided.Non &&  // 部分語の3文字語は除外
                (CodeCheck.IsHangul(wt.word) ||
                 CodeCheck.IsKanji(wt.word))
                )
            {
                WordChain wc3 = Check3Chars(wt);
                if (wc3 != null)
                {
                    return(wc3);
                }
            }

//            int target_len=2;   // 2005.09.03 やっぱり1文字まで切らないとだめだ
            int target_len = 1;
            int str_len    = str.Length;

            int       minimumCost      = 9999;
            WordChain minimumCostChain = null;

            // 前から1文字ずつ落としつつ,検索。

            while (true)
            {
                int start = str_len - target_len;
//                if( start <= 1 ){  // 2005.09.03
                if (start <= 0)
                {
                    break;
                }
                // 文字列を分割する
                // str --> str2 + str3
                //       String str2 = str.Remove   (start,  target_len );
                //       String str3 = str.Substring(start,  target_len );
                // 前から分割に変えた(2005.08)
                String str2 = str.Remove(target_len, start);
                String str3 = str.Substring(target_len, start);  //あとできれいに

                // 前と後ろを、それぞれ検索
                WordChain wc2 = DividedWordSearch(str2);
                WordChain wc3 = DividedWordSearch(str3);

                #if DEBUG_LOG
                KJ_Analyzer.WriteDebugLog("str2/str3:" + str2 + "/" + str3);
                #endif

                WordTable wt2, wt3;
                if (wc2 == null)
                {
                    wt2 = new WordTable(str2);
                    wc2 = new WordChain(wt2);
                }
                if (wc3 == null)
                {
                    wt3 = new WordTable(str3);
                    wc3 = new WordChain(wt3);
                }

                // 分割情報設定
                if (wt.divided == Divided.Non)
                {
                    wc2.Head.divided = Divided.Lead;
                    wc3.Head.divided = Divided.Trail;
                }
                if (wt.divided == Divided.Lead)
                {
                    wc2.Head.divided = Divided.Lead;
                    wc3.Head.divided = Divided.Middle;
                }
                if (wt.divided == Divided.Middle)
                {
                    wc2.Head.divided = Divided.Middle;
                    wc3.Head.divided = Divided.Middle;
                }
                if (wt.divided == Divided.Trail)
                {
                    wc2.Head.divided = Divided.Middle;
                    wc3.Head.divided = Divided.Trail;
                }

                // wc2とwc3をつなぐ
                wc2.Add(wc3);

                //  wc2---wc3 のコストを計算
                int divChainCost = wc2.GetChainCost();
                if (minimumCost >= divChainCost)
                {
                    minimumCostChain = wc2;
                    minimumCost      = divChainCost;    //最小コストの更新
                }

                #if DEBUG_LOG
                KJ_Analyzer.WriteDebugLog("wc2:" + wc2.Head.word + "," + wc2.Head.Cost);
                KJ_Analyzer.WriteDebugLog("wc3:" + wc3.Head.word + "," + wc3.Head.Cost);
                KJ_Analyzer.WriteDebugLog("divChainCost:" + divChainCost);
                #endif


                target_len++;
            } // end of while


            // Chain中のwordが全て翻訳できていない
            if (minimumCostChain == null ||
                (minimumCostChain != null && !minimumCostChain.IsTranslated()))
            {
                return(null);
            }

            // 翻訳できていない部分chainを再起実行
            WordTable subT = minimumCostChain.Head;
            while (subT != null)
            {
                if (!subT.IsTranslated())
                {
                    WordChain subWc = WordPartProc(subT);
                    if (subWc != null)
                    {
                        WordTable wNext = subT.next;
                        minimumCostChain.Swap(subT, subWc);
                        subT = wNext;
                        continue;
                    }
                }
                subT = subT.next;
            }

            return(minimumCostChain);
        }