Esempio n. 1
0
        //--------------------------------------------------------------------
        // 完全一致の辞書検索 (再起にすると時間がかかりすぎるので再起なし)
        //
        static public WordChain  DividedWordSearch(string str)
        {
            WordTable wt;
            WordChain wc;

            #if DEBUG_LOG
            KJ_Analyzer.WriteDebugLog("DividedWordSearch:" + str);
            #endif

            SearchResult sResult = KJ_dict.SearchFull(str);

            if (sResult == null)
            {
                // strが辞書にない
                // wc = WordPartProc(wt);
                return(null);
            }

            wt = new WordTable(str);
            wc = new WordChain();

            // 検索できた
            wt.SetResult(sResult); // wt3に検索結果を入れる
            //wt.IsDevided=true;  // 分割語であるマーク

            wc.Add(wt);

            return(wc);
        }
Esempio n. 2
0
        //---------------------------------------------------------------------
        // 入力文字列の変換を試みる。
        public String Trans(String inputstring)
        {
            TextScanner scanner = new TextScanner();

            // ブラウザからならHTMLとしてscanさせる(タグをまとめる)
            if (isBrowser)
            {
                scanner.htmlText = true;
            }

            // inputstringを語のchainに分解する
            WordChain wc = scanner.Scan(inputstring);

            if (this.pBar != null)
            {
                this.pBar.Maximum = wc.Length * 2;
            }

            // 形態素解析 & 翻訳処理  (本格的じゃないよ)
            KJ_Analyzer analyzer = new KJ_Analyzer(this);

            wc = analyzer.MorphologicScan(wc);  // 翻訳はここ



            // WordChainから翻訳後文字列を作り出す
            if (showoriginal)
            {
                return(Chain2String_for_Web(wc)); // Web用
            }
            else
            {
                return(Chain2String(wc));
            }
        }
Esempio n. 3
0
        //--------------------------------------------------------------


        //------------------------------------------------------------------
        // 分割も考慮し詳しい(?)解析
        //    分解後チェーンの最後のwTableを返す
        //
        //
        //    PalDalHan   WordTable   ←input
        //      ↓
        //    PalDal      WordTable
        //    Han         WordTable   ←return
        //
        private WordTable ScanDetail(WordChain wChain, WordTable wTable)
        {
            if (wTable.IsTranslated())
            {
                return(wTable);  // 変換済みなら何もしない
            }

            #if DEBUG_LOG
            KJ_Analyzer.WriteDebugLog("ScanDetail");
            #endif

            // 各国固有部
            if (KJ_dict.inputIsHangul)
            {
                WordTable rtnWt = ScanDetailKr(wChain, wTable);
                if (rtnWt != null)
                {
                    return(rtnWt);
                }
            }
            else
            {
                WordTable rtnWt = ScanDetailJp(wChain, wTable);
                if (rtnWt != null)
                {
                    return(rtnWt);
                }
            }


            // 語分割ありで、熟語をチェック
            WordTable idiomwt = Idiom.Search2(wChain, wTable);
            if (idiomwt != null)
            {
                // 熟語が解決できた
                return(idiomwt);
            }

            // 語の分解
            WordChain devChain = WordDivider(wTable);
            if (devChain != null)                          // 分解できた?
            {
                if (AcceptableTransWord(wTable, devChain)) // 採用できるか?

                // 採用できるならwTableを分解したチェーンdevChainで入れ替え
                {
                    wChain.Swap(wTable, devChain);

                    return(devChain.Tail);       // 分解した最後の位置へ
                }
            }

            // それでも変換なしならカタカナまたはハングルに自動変換
            wTable = ConvAutoConv(wTable);

            return(wTable);
        }
Esempio n. 4
0
        //----------------------------------------------------------------
        // 語分割ありの熟語チェック
        //     공부하지는 못할 것이라는==> 공부 + 하지는 못할 것이라는
        //     ~~~~~~~~~~                         ~~~~~~~~~~~~~~~~~~~~
        //      startwt                       ここのWordTableはdivided=Trail
        //
        static public WordTable  Search2(WordChain wc, WordTable startwt)
        {
            String str = startwt.word;

            if (!startwt.IsWord())
            {
                return(null);     // 空白などで始まる場合は、は処理しない
            }

            int target_len = 1;
            int str_len    = str.Length;

            // 前から1文字ずつ落としつつ,熟語検索。
            while (true)
            {
                if (target_len >= str_len)
                {
                    break;
                }

                // 文字列を分割する
                // str --> str2 + str3
                String str2 = str.Substring(0, target_len);
                String str3 = str.Remove(0, target_len);

                WordTable wt3 = new WordTable(str3);
                wt3.next = startwt.next;
                wt3.prev = startwt.prev;
                WordTable idiomTable = Idiom.Search(wc, wt3);

                if (idiomTable != null)
                {
                    // 熟語確定
                    WordTable wt2 = new WordTable(str2);
                    wc.InsertBefore(idiomTable, wt2);

                    WordChain wc2 = KJ_Analyzer.WordPartProc(wt2);
                    if (wc2 != null)
                    {
                        wc.Swap(wt2, wc2);
                    }
                    idiomTable.divided = Divided.Trail;
                    return(idiomTable);
                }

                target_len++;
            }

            return(null);
        }
Esempio n. 5
0
        //-------------------------------------------------------
        // 翻訳のメイン
        //     KJ_browserの中にも同じものをコピーで持っている点注意
        //
        public WordChain MorphologicScan(WordChain wChain)
        {
            #if DEBUG_LOG
            KJ_Analyzer.StartDebugLog();
            KJ_Analyzer.WriteDebugLog("MorphologicScan");
            #endif

            if (!wChain.Exist())
            {
                return(wChain);
            }

            WordTable wTable = wChain.Head;

            // 解析ループ  1回目
            // 翻訳前処理(助詞分離など先に  熟語の精度を上げるため)
            //  고정 관념을 ---> 고정 관념 을に分離しておくため(熟語判定用)
            while (wTable != null)
            {
                this.sTrans.pBarStep(); // プログレスバーを進める


                // 1回目処理
                wTable = firstScan(wChain, wTable);

                wTable = wTable.next;   // 次の語へ
            } // 翻訳前処理ここまで


            // 解析ループ  2回目  (翻訳のメインループ)
            wTable = wChain.Head;  //   再度先頭から
            while (wTable != null)
            {
                this.sTrans.pBarStep(); // プログレスバーを進める


                // 2回目処理
                wTable = secondScan(wChain, wTable);

                wTable = wTable.next;   // 次の語へ
            } // 翻訳のメインループ ここまで

            #if DEBUG_LOG
            KJ_Analyzer.EndDebugLog();
            #endif

            return(wChain);
        }
Esempio n. 6
0
        //------------------------------------------------------------------
        private WordChain WordDivider(WordTable wTable)
        {
            WordChain wc1 = null;

            #if DEBUG_LOG
            KJ_Analyzer.WriteDebugLog("WordDivider");
            #endif

            // 辞書検索なしの助詞チェック
            if (KJ_dict.inputIsHangul)
            {
                wc1 = KJ_pp.CheckPPwithoutDictKr(wTable);
            }

            // 3文字の「ハングルまたは漢字」なら特別チェック
            if (wTable.word.Length == 3 &&
                (CodeCheck.IsHangul(wTable.word) ||
                 CodeCheck.IsKanji(wTable.word))
                )
            {
                WordChain wcThree = Check3Chars(wTable);
                if (wcThree != null)
                {
                    return(wcThree);
                }
            }


            // 全体でmatchしないなら部分文字列で検索(再起 語分解あり)
            WordChain wc2 = null;
            wc2 = WordPartProc(wTable);

            // wtは最後の語テーブル。未変換なら再調査
            //        WordChain wc3 = CheckLastWord(wChain, wTable);


            // costが小さい方を採用
            WordChain rtnWc = WordChain.GetMinimunCostChain(wc1, wc2);

            return(rtnWc);
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        //-------------------------------------------------------
        // 辞書チェックなしのハングル助詞チェック
        //
        //    末尾が助詞と一致するなら分離する。
        //
        static public WordChain CheckPPwithoutDictKr(WordTable wt)
        {
            if (wt.IsTranslated())
            {
                // 翻訳済みなら何もしない。
                return(null);
            }
            if (wt.charCategory != CharCategory.Hangul &&
                wt.charCategory != CharCategory.LetterMix)
            {
                // ハングルでないなら、または英字+ハングルでないなら何もしない。
                return(null);
            }

            WordTable rtnWt = wt;   // 戻りのdefault

            StringDivider sd = new  StringDivider(wt.word);

            string trans = "";

            // 前から1文字ずつ落としつつ,検索。
            while (sd.eof() == false)
            {
                // 文字列を分割する
                HYAM.KJ_dict.Pair pair = sd.DivideForward();

                if (Hangul.withPachim(pair.head))
                {
                    trans = KJ_Filter.SearchPP_Pachim(pair.tail);
                }
                else
                {
                    trans = KJ_Filter.SearchPP_NoPachim(pair.tail);
                }

                if (trans == "")
                {
                    continue;
                }

                // wtをwt1とwt2に分割
                WordTable wt1 = new WordTable(pair.head);
                wt1.divided = Divided.Lead;

                //  分離できた。 wT2は助詞と仮定。訳語も入れておく
                WordTable wt2 = new WordTable(pair.tail, trans);
                wt2.posCategory = PosCategory.PP;
                wt2.Cost        = 2;
                wt2.divided     = Divided.Trail;


                WordChain rtnChain; // 返却チェーン
                // wt1を調査
                //  (未知語なので分割してみる)
                WordChain wc1 = KJ_Analyzer.WordPartProc(wt1);

                if (wc1 == null)
                {
                    // 分割できなかった
                    rtnChain = new WordChain(wt1, wt2);
                }
                else
                {
                    wc1.Add(wt2);
                    rtnChain = wc1;
                }

                return(rtnChain);
            }

            return(null);  // 分離できなかったらnullを返す
        }