Exemple #1
0
        //-------------------------------------------------------
        // 語のchainを先頭から舐め、熟語を探す。
        static public WordTable Scan(WordChain wChain, WordTable wTable)
        {
            // 熟語は優先のため変換済みチェックなし
            //if(wTable.IsTranslated()){
            //    return wTable;  // 変換済みなら何もしない
            //}

            // wtで始まる熟語のチェック
            WordTable idiomwt = Idiom.Search(wChain, wTable);

            if (idiomwt != null)
            {
                // 熟語が解決できた
                return(idiomwt);
            }

            return(wTable);
        }
Exemple #2
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);
        }
Exemple #3
0
        // Chainの最後にChainを追加
        public void Add(WordChain wc2)
        {
            if (wc2 == null)
            {
                return; // 何もしない
            }
            if (head == null)
            {
                this.head = wc2.head;
                this.tail = wc2.tail;
                return;
            }

            this.tail.next = wc2.head;
            wc2.head.prev  = this.tail;

            this.tail = wc2.tail;
        }
Exemple #4
0
        //  前の有効な語を返す。(空白skip)
        public WordTable PrevWord()
        {
            WordTable wt = this.prev;

            while (true)
            {
                if (wt == null)
                {
                    break;
                }

                if (wt.IsWord())
                {
                    return(wt);
                }
                wt = wt.prev;
            }
            return(null);
        }
Exemple #5
0
        //---------------------------------------------
        //  次の有効な語を返す。(空白skip)
        public WordTable NextWord()
        {
            WordTable wt = this.next;

            while (true)
            {
                if (wt == null)
                {
                    break;
                }

                if (wt.IsWord())
                {
                    return(wt);
                }
                wt = wt.next;
            }
            return(null);
        }
Exemple #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);
        }
Exemple #7
0
        //--------------------------------------------------------------
        public WordTable firstScan(WordChain wChain, WordTable wTable)
        {
            // 速度向上のため、skipさせる
            if (wTable.IsTransSkipWord())
            {
                return(wTable);      // 何もせずreturn
            }

            // 前処理
            wTable = ChainPreProc(wChain, wTable);

            // 数助詞,冠数詞をチェック
            wTable = Numerative.Scan(wChain, wTable);

            // 助詞の解析を試す (前の語の辞書引きあり)
            wTable = KJ_pp.Scan(wChain, wTable);        //2005.08.26 数詞の前に

            return(wTable);
        }
Exemple #8
0
        //-------------------------------------------------------
        static private WordChain DivideCountableMain(WordTable wTable, PosCategory poscategory)
        {
            WordChain wc = null;

            StringDivider sd = new  StringDivider(wTable.word);

            // 後から1文字ずつ落としつつ,検索。
            string trans = "";

            while (sd.eof() == false)
            {
                // 文字列を分割する
                HYAM.KJ_dict.Pair pair = sd.DivideBackward();

                if (poscategory == PosCategory.Numeral)
                {
                    trans = KJ_Filter.SearchNumeral(pair.head);
                }
                else
                {
                    trans = KJ_Filter.SearchNumerative(pair.head);
                }

                if (trans != "")
                {
                    WordTable wt_num = new WordTable(pair.head, trans);
                    wt_num.posCategory = poscategory;
                    wc = new WordChain(wt_num);

                    if (pair.tail != "")
                    {
                        WordTable wt_tail = new WordTable(pair.tail);
                        wc.Add(wt_tail);
                    }

                    return(wc);
                }
            }  // end of while


            return(null);
        }
Exemple #9
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);
        }
Exemple #10
0
        //--------------------------------------------------------------
        public WordTable secondScan(WordChain wChain, WordTable wTable)
        {
            // 速度向上のため、skipさせる
            if (wTable.IsTransSkipWord2()) // 少しゆるいskip
            {
                return(wTable);            // 何もせずreturn
            }

            // 熟語をチェック
            wTable = Idiom.Scan(wChain, wTable);

            // 分割なし完全一致の語
            wTable = DelimitedWord.Scan(wChain, wTable);

            // 分割も考慮し詳しい(?)解析
            //    (辞書引きなし助詞解析あり)
            //     分解した最後のwTableを返す
            wTable = ScanDetail(wChain, wTable);

            return(wTable);
        }
Exemple #11
0
 //-------------------------------------------------------------------
 // 形容動詞の語幹となる名詞なら,その日本語訳を返す
 private string IsNounWithAdverb(WordTable wTable)
 {
     if (wTable.sResult == null)
     {
         return("");
     }
     if (wTable.sResult.documents == null)
     {
         return("");
     }
     // wTableはハダ動詞(動詞・形容動詞)になる名詞?
     foreach (DocumentData sdata in wTable.sResult.documents)
     {
         string src = sdata.GetSrc();
         if (src == "hyam(noun.adverb)")
         {
             return(sdata.GetData("key2"));
         }
     }
     return("");
 }
Exemple #12
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);
        }
Exemple #13
0
        //-------------------------------------------------------------------
        //
        private WordTable ScanDetailJp(WordChain wChain, WordTable wTable)
        {
            //  助詞を処理
            //   (助詞で始まる熟語があるので熟語の後)
            if (wTable.posCategory == PosCategory.PP)
            {
                // 改めて訳語を設定
                string pp = KJ_pp.TransJapanesePP(wTable);
                if (pp != "")
                {
                    // 訳語設定
                    wTable.transWord = pp;
                    wTable.Cost      = 0;

                    // ハングルの助詞なら、分かち書きのため空白を置く。
                    wTable.transWord = wTable.transWord + " ";
                    return(wTable);
                }
            }

            return(null);
        }
Exemple #14
0
        //-------------------------------------------------------------------
        private void MakeDebugInfo(StringBuilder result, WordTable wt)
        {
            string indent = "    ";

            result.Append(indent);
            result.Append(" (" + wt.charCategory + ") ");
            result.Append(" (" + wt.posCategory + ") ");
            result.Append(" (" + wt.GetWordCost() + ") ");
            result.Append(" (" + wt.divided + ") ");

            if (wt.IsSentenseHead)
            {
                result.Append(" (sentense head)");
            }
            if (wt.IsSentenseTail)
            {
                result.Append(" (sentense tail)");
            }
            result.Append("\n");

            SearchResult sResult = wt.sResult;

            if (sResult != null && sResult.documents != null)
            {
                foreach (DocumentData ddata in sResult.documents)
                {
                    result.Append(indent);
                    result.Append(ddata.GetData("key2"));
                    result.Append(" " + ddata.GetData("cost2"));
                    result.Append(" " + ddata.GetData("src"));
                    result.Append("\n");
                }
            }
            else
            {
                result.Append("\n");
            }
        }
Exemple #15
0
        //-------------------------------------------------------------------
        // 形容動詞の語尾か?
        private string IsAdverbTail(WordTable wTable)
        {
            if (wTable.sResult == null)
            {
                return("");
            }
            if (wTable.sResult.documents == null)
            {
                return("");
            }

            // wTableはハダ形容動詞の語尾?
            foreach (DocumentData sdata in wTable.sResult.documents)
            {
                string src = sdata.GetSrc();
                if (src == "hyam(adverb.hada.parts)")
                {
                    return(sdata.GetData("key2"));
                }
            }

            return("");
        }
Exemple #16
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);
        }
Exemple #17
0
        //----------------------------------------------
        //
        //          wt2
        //           |
        //           v
        //  ----wt1--------a---------b--------c-----
        //              (oldnext)
        public void Insert(WordTable wt1, WordTable wt2)
        {
            if (wt1 == null)
            {
                this.head = wt2;
                this.tail = wt2;
                return;
            }
            if (wt1.next == null)
            {
                Debug.Assert(this.tail == wt1);
                wt1.next  = wt2;
                wt2.prev  = wt1;
                wt2.next  = null;
                this.tail = wt2;
                return;
            }
            WordTable oldnext = wt1.next;

            wt1.next     = wt2;
            wt2.prev     = wt1;
            wt2.next     = oldnext;
            oldnext.prev = wt2;
        }
Exemple #18
0
        //------------------------------------------------------------------
        // 4文字語の調査 (部分分割後は使わない)
        static private WordChain Check4Chars(WordTable wTable)
        {
            SearchResult sResult;

            if (KJ_dict.inputIsHangul)
            {
                // 4文字以外は抜ける。
                if (wTable.word.Length != 4)
                {
                    return(null);
                }

                if (wTable.word.EndsWith("하게"))
                {
                    string head = wTable.word.Remove(2, 2);  // 4文字なので固定
                    sResult = KJ_dict.SearchFull(head);
                    if (sResult != null)
                    {
                        WordTable tempwt = new WordTable(head);
                        tempwt.SetResult(sResult);
                        string trans = tempwt.GetTranslatedText();

                        wTable.transWord   = trans + "に";
                        wTable.Cost        = 10;
                        wTable.posCategory = PosCategory.PP;

                        WordChain wc = new  WordChain(wTable);

                        // これだけならwtでもいいが、汎用化のためwcで返す
                        return(wc);
                    }
                }
            }

            return(null);
        }
Exemple #19
0
        //-------------------------------------------------------
        // wordがハングルの助詞と完全一致なら、訳語をreturn で返す。
        static private String  CheckHangulPP_Full(WordTable wordT)
        {
            string word     = wordT.word;
            string prevword = "";

            if (wordT.prev == null)
            {
                return("");
            }

            // 前の語が空白なら助詞とは判断しない。
            //     초파리에서 이 유전자를 の「이」は「が」ではない
            if (!wordT.prev.IsWord())
            {
                return("");  // 何もせず抜ける
            }

            prevword = wordT.prev.word;   // 前の語

            // 前の語がハングルならつながっているから
            // このタイプの判断が必要なのは前が英数字
            //   ex.    MP3의
            return(KJ_Filter.SearchPPall(word));
        }
Exemple #20
0
 //----------------------------------------------
 //
 //  chain中のwt1を別chainで置き換える
 //
 //      wc( wt2----------wt3---------wt4 )
 //      |   wc.head                  wc.tail
 //      v
 //  ----wt1--------a---------b--------c-----
 //              (oldnext)
 //
 public void Swap(WordTable wt1, WordChain wc)
 {
     Insert(wt1, wc);
     Delete(wt1);
 }
Exemple #21
0
 //----------------------------------------------
 //
 //  chain中のwt1を wt2+wt3に置き換える
 //
 public void Swap(WordTable wt1, WordTable wt2, WordTable wt3)
 {
     Insert(wt1, wt2);
     Insert(wt2, wt3);
     Delete(wt1);
 }
Exemple #22
0
 //--------------------------------------------
 // constructor
 public WordChain()
 {
     this.head = null;
     this.tail = null;
 }
Exemple #23
0
        //--------------------------------------------------------------
        // startwtで始まる熟語を最長一致でチェックする
        //
        // (before)
        //  -----wt1-----wt2-----wt3-----wt4-----wt5-----wt6-----
        //               ↑              ↑
        //              startwt         matched
        //
        // (after)
        //  -----wt1-----idiomwt-----wt5-----wt6-----
        //
        //  チェーン中の熟語を成すテーブルは1つにまとめる。
        //    (正確には熟語のテーブルを挿入し、個々の語のテーブルは削除)
        //
        static public WordTable  Search(WordChain wc, WordTable startwt)
        {
            //熟語は語単位より優先
            //   if(startwt.IsTranslated()){
            //       return  null; // 翻訳済みの語は触らない
            //   }

            bool isExist;                // 辞書中にチェック対象の語(熟語)が存在するか?

            WordTable    idiomwt = null; // 熟語テーブル
            SearchResult sResult;
            string       word = startwt.word;

            // startwtが翻訳済みで助詞なら何もしない
            // 暫定的 2005.08.26
            //    if(startwt.IsTranslated() && startwt.pos == PosCategory.PP ){
            //        return(null);   // not found
            //  }

            // 前方一致で該当なしなら
            // この語で始まる熟語は辞書にない
            isExist = KJ_dict.CheckForward(word);
            if (!isExist)
            {
                return(null);   // not found
            }

            // 前方一致でmatchしたので先読みして熟語チェック
            String    word2     = "";
            string    next      = "";
            WordTable nextTable = startwt.next;
            WordTable matched   = startwt;

            // 次の語以降を足しながらチェック
            while (nextTable != null)
            {
                if (nextTable == null || nextTable.word == "")
                {
                    break;  // 次の語なしなら抜ける
                }
                next = nextTable.word;
                char ch = next[0];
                if (Char.IsSeparator(ch))
                {
                    next = " ";
                }

                if (next == " ")
                {
                    word      = word + next;
                    nextTable = nextTable.next; // 次の語へ
                    continue;                   // 空白付加だけでは再検索しない
                }

                word2 = word + next;
                //次の語を足して前方一致チェック
                isExist = KJ_dict.CheckForward(word2);
                if (!isExist)
                {
                    // nextを足したら,一致しない。→ これ以上先を見る必要なし


                    break;
                }

                // 一致した部分まででで完全一致検索
                sResult = KJ_dict.SearchFull(word2);
                if (sResult != null)
                {
                    // string trimword = word2;
                    // trimword = trimword.Replace(" ", ""); // 空白削除
                    if (IsValidIdiom(sResult))  // 長さ4以上でないと採用しない
                    // 熟語が見つかった
                    {
                        idiomwt = new WordTable(word2);
                        idiomwt.charCategory = startwt.charCategory;
                        // 先頭文字種で (混ざっている可能性あるが)
                        idiomwt.posCategory = PosCategory.Idiom;
                        idiomwt.SetResult(sResult);
                        matched = nextTable; // 完全一致した最後のテーブル
                    }
                }

                // さらに次の語へ
                word      = word2;          // nextを足したものを元とする。
                nextTable = nextTable.next; // 次の語へ
            } // while loop


            if (startwt.word == word)
            {
                // 熟語でなく単なる入力語の完全一致の時は返さない
                return(null);
            }

            if (idiomwt != null)
            {
                // 熟語が見つかっている

                wc.Insert(matched, idiomwt);

                // startwtからmatchedまでは消していい。
                WordTable delwt = startwt;
                while (true)
                {
                    wc.Delete(delwt);
                    if (delwt == matched)
                    {
                        break;
                    }
                    delwt = delwt.next;
                }

                // 熟語のテーブルを返す
                return(idiomwt);
            }

            // 熟語なし
            return(null);
        }
Exemple #24
0
        //-------------------------------------------------------
        static private WordChain  DivideJapanesePP(WordTable wTable)
        {
            StringDivider sd = new  StringDivider(wTable.word);

            // 前から1文字ずつ落としつつ,検索。
            string trans = "";

            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;
                }

                SearchResult result = KJ_dict.SearchFull(pair.head);

                if (result != null)
                {
                    // 助詞確定

                    // 助詞に先行しない語は除外
                    //   산은  (은が助詞なら、산は動詞[連体詞]ではない)
                    //   result = SearchResult.CheckPPConnectable(result);

                    // もし語が全部落ちたならば何もしない
                    if (result.documents.Count == 0)
                    {
                        // nop
                    }
                    else
                    {
                        // 先行語+助詞のチェーンを作る
                        WordTable wt1 = new WordTable(pair.head);
                        wt1.SetResult(result);
                        wt1.divided = Divided.Lead;

                        // wt2.transWord はまだ設定しない。
                        //   前の訳語のパッチムに影響されるため。
                        WordTable wt2 = new WordTable(pair.tail);
                        wt2.posCategory = PosCategory.PP;
                        wt2.divided     = Divided.Trail;

                        // 長い助詞ほどコストを低くする
                        // wt2.Cost      = 0;
                        if (wt2.word.Length > 2)
                        {
                            wt2.Cost = 0;
                        }
                        else if (wt2.word.Length == 2)
                        {
                            wt2.Cost = 3;
                        }
                        else
                        {
                            wt2.Cost = 5;
                        }

                        WordChain rtnChain = new WordChain(wt1, wt2);

                        return(rtnChain);
                    }
                }
            }  // end of while


            return(null);  // 分離できなかったらnullを返す。
        }
Exemple #25
0
        //-------------------------------------------------------
        // 語のchainを先頭から舐め、助詞(Postpositional Particle)を分解する。
        static private WordTable ScanPPKr(WordChain wChain, WordTable wTable)
        {
            bool inputIsHangul = KJ_dict.inputIsHangul;

            // 語を舐め、助詞を分解する。

            if (wTable.charCategory != CharCategory.Hangul &&
                wTable.charCategory != CharCategory.LetterMix)
            {
                // ハングルでないなら、または英字+ハングルでないなら何もしない。
                return(wTable);
            }


            // 完全一致の助詞なら情報をセットし、終了
            string pp_trans = CheckHangulPP_Full(wTable);

            if (pp_trans != "")
            {
                wTable.transWord   = pp_trans;
                wTable.posCategory = PosCategory.PP;
                if (wTable.word.Length > 2)
                {
                    wTable.Cost = 0;
                }
                else if (wTable.word.Length == 2)
                {
                    wTable.Cost = 3;
                }
                else
                {
                    wTable.Cost = 5;
                }

                return(wTable);
            }

            // wordTableが辞書に完全一致で存在するか調べる。
            bool isExist = KJ_dict.CheckFull(wTable.word);

            if (isExist)
            {
                // 完全一致した語は判定せず、なにもしない。
                return(wTable);
            }


            // 助詞の分解を試みる
            WordChain resultChain = DivideHangulPP(wTable);

            if (resultChain == null)
            {
                // 助詞はついてなかった。なにもしない。
                return(wTable);
            }

            // resultChainは 語+助詞のチェーン。WordTと入れ替える
            wChain.Swap(wTable, resultChain);

            // 助詞で始まる熟語でないかチェック
            WordTable idiomwt = Idiom.Search(wChain, resultChain.Tail);

            // resultChainの先頭は未処理。
            // いったんcurrentをresultChainの先頭に戻す
            //     위원회를 --->    위원회          +   를
            //      wTable        resultChain.Head     [を]:翻訳済み
            wTable = resultChain.Head;


            return(wTable);
        }
Exemple #26
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);
        }
Exemple #27
0
        //-------------------------------------------------------------------
        // WordChainの各WordTableから翻訳結果を取り出し翻訳後文字列を返す
        //   (ブラウザ用)
        public String Chain2String_for_Web(WordChain wc)
        {
            StringBuilder result;           // 出力文字列

            result = new StringBuilder();


            string translatedText = "";
            string originalText   = ""; // 先頭にマーカ


            // 語のchainを先頭から舐め、翻訳結果をresultに順次追加。
            WordTable wt = wc.Head;

            while (wt != null)
            {
                // タグの内容のテーブル
                if (wt.charCategory == CharCategory.HTMLtag)
                {
                    if (translatedText.Trim() != "")
                    {
                        if (String.Compare(originalText, translatedText) != 0)
                        {
                            // 翻訳データを埋める
                            originalText += ("<font color=blue size=-1>" +
                                             translatedText + "</font>");
                        }
                        else
                        {
                            // NOP
                            //  英文など無変換のものは併記しない
                        }

                        result.Append(originalText);

                        // バッファクリア
                        originalText   = "";
                        translatedText = "";
                    }

                    // htmlタグのwordをそのまま追加
                    result.Append(wt.word);

                    // この書き換えは効かない... [2009/09/26 09:56:07]
                    //       string noblank = wt.word.Replace("target=\"_blank\"", "");
                    //       result.Append( noblank );

                    wt = wt.next;
                    continue;
                }


                // htmlタグの外 (訳すべきテキスト)

                // 原文の退避
                originalText += wt.word;


                // 翻訳用前処理
                TranslationPreproc(wt);

                // wtから翻訳済みテキストを取り出す
                string translated = wt.GetTranslatedText();
                // 翻訳できなかったら元文字をそのまま返す
                if (translated == "")
                {
                    translated = wt.word;
                }

                translatedText += translated;


                wt = wt.next;
            }


            return(result.ToString());
        }
Exemple #28
0
 public WordChain(WordTable wt1, WordTable wt2) : this()
 {
     this.Add(wt1);
     this.Add(wt2);
 }
Exemple #29
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);
        }
Exemple #30
0
        //--------------------------------------------------------------
        // 非常に簡易的な文字列分解。文字種が変わった所で切る。
        //   this.inputString から文字を取り出し
        //   語(と思われる)単位にまとめて,その語をWordTableで返す。
        private WordTable  PicupWordTable()
        {
            StringBuilder rtn_str = new StringBuilder();

            rtn_str.Length = 0;

            bool inHTMLtag = false;  // Tagの中か否か?

            // 採取取り出し文字の文字種
            CharCategory lastCharCategory = CharCategory.Null;

            // 取り出す語の文字種
            CharCategory charCategory = CharCategory.Null;

            WordTable wordT = new WordTable();

            while (true)
            {
                if (this.stringIndex >= this.inputString.Length)
                {
                    break;
                }

                // 入力文字列のinstr_inex位置から 1文字取り出し
                char ch = this.inputString[this.stringIndex];

                // 取り出した文字の種別を判定
                lastCharCategory = GetCharCategory(ch);


                //  例えば <font size=+1>の "<"から ">"までを
                //  HTMLtagというカテゴリにまとめる。
                if (this.htmltext)
                {
                    if (ch == '<')
                    {
                        inHTMLtag = true;
                    }
                    if (inHTMLtag)
                    {
                        lastCharCategory = CharCategory.HTMLtag;
                    }
                    if (ch == '>')
                    {
                        inHTMLtag = false;
                    }
                }



                if (charCategory != CharCategory.Null)
                {
                    if (charCategory != lastCharCategory)
                    {
                        break;   // 文字種が変わったら抜ける
                    }
                }
                else
                {
                    charCategory = lastCharCategory;
                }

                rtn_str.Append(ch.ToString());

                this.stringIndex++; // 取り出し位置を進める
            }

            wordT.word         = rtn_str.ToString();   // 文字列の設定
            wordT.charCategory = charCategory;         // 文字種別の設定


            if (charCategory == CharCategory.Katakana)
            {
                wordT.posCategory = PosCategory.Noun;
            }
            else if (charCategory == CharCategory.HiraganaWo)
            {
                wordT.posCategory = PosCategory.PP;
                wordT.Cost        = 0;
            }
            else if (charCategory == CharCategory.Other)
            {
                wordT.posCategory = PosCategory.Other;
                wordT.Cost        = 0;
            }
            else if (charCategory == CharCategory.Separator)
            {
                wordT.posCategory = PosCategory.Other;
                wordT.Cost        = 0;
            }
            else
            {
                wordT.posCategory = PosCategory.Other;
            }

            return(wordT);
        }