コード例 #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);
        }
コード例 #2
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);
        }
コード例 #3
0
        //------------------------------------------------------------------
        // Chain中が全て翻訳済みWordTableならtrue
        // 1つでも翻訳できていないならfalse
        public bool IsFullTranslated()
        {
            WordTable wt = this.head;

            while (wt != null)
            {
                if (!wt.IsTranslated())
                {
                    return(false);
                }
                wt = wt.next;
            }
            return(true);
        }
コード例 #4
0
        //------------------------------------------------------------------
        // Chain中の何文字翻訳できているか
        public int TranslatedCharCount()
        {
            WordTable wt     = this.head;
            int       rtnCnt = 0;

            while (wt != null)
            {
                if (wt.IsTranslated())
                {
                    rtnCnt += wt.word.Length;
                }
                wt = wt.next;
            }
            return(rtnCnt);
        }
コード例 #5
0
        static public WordTable Scan(WordChain wChain, WordTable wTable)
        {
            if (wTable.IsTranslated())
            {
                return(wTable);  // 変換済みなら何もしない
            }

            if (KJ_dict.inputIsHangul)
            {
                wTable = ScanPPKr(wChain, wTable);
            }
            else
            {
                wTable = ScanPPJp(wChain, wTable);
            }

            return(wTable);
        }
コード例 #6
0
        //-------------------------------------------------------------------
        // チェーンの前処理。
        //     句読点の判定、置換など
        //
        private WordTable ChainPreProc(WordChain wChain, WordTable wTable)
        {
            if (wTable.IsTranslated())
            {
                return(wTable);  // 変換済みなら何もしない
            }

            if (wTable.charCategory == CharCategory.Letter)
            {
                // 一種の正規化
                if (wTable.word == "ㆍ")     // 0x318D  韓国で使われる中点
                {
                    wTable.word = "・";      // 0x30FB  日本語の全角中点
                }
            }

            if (wTable.charCategory == CharCategory.Punctuation)
            {
                if (KJ_dict.inputIsHangul)
                {
                    if (wTable.word == ".")
                    {
                        if (wTable.next == null || !wTable.next.IsWord())
                        {
                            wTable.transWord = "。";
                        }
                    }
                }
                else
                {
                    if (wTable.word == "、")
                    {
                        wTable.transWord = ", ";
                    }
                    if (wTable.word == "。")
                    {
                        wTable.transWord = ". ";
                    }
                }
            }

            return(wTable);
        }
コード例 #7
0
        //------------------------------------------------------------------------
        // 辞書に見つからなかった語を自動変換する
        //   ハングル <---> カタカナ
        private WordTable ConvAutoConv(WordTable wt)
        {
            if (wt.IsTranslated())
            {
                return(wt);  // 変換済みなら何もしない
            }

            if (!this.sTrans.AutoConv)
            {
                return(wt);  // AutoConvをoffにしている場合は何もせず抜ける。
            }

            if (KJ_dict.inputIsHangul)
            {
                // K-->J方向
                if (CodeCheck.IsHangul(wt.word))
                {
                    wt.transWord = Hangul.Hangul2Kana(wt.word);
                }
            }
            else
            {
                // J-->方向
                if (wt.charCategory == CharCategory.Katakana)
                {
                    // カタカナの場合
                    wt.transWord = Kana.Kana2Hangul(wt.word);
                }
                else
                {
                    if (wt.charCategory == CharCategory.Hiragana)
                    {
                        // ひらがなの場合
                        wt.transWord = Kana.Hira2Hangul(wt.word);
                    }
                }
            }

            return(wt);
        }
コード例 #8
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);
        }
コード例 #9
0
ファイル: KJ_Numerative.cs プロジェクト: hyamhyam/kj_dict
        //-------------------------------------------------------
        // 語の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);
        }
コード例 #10
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);
        }
コード例 #11
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を返す
        }