/** * @version $Id: SynonymCorrector.java 1840 2014-04-16 05:38:34Z yukihiro-kinjyo $ * * 2011/10/13 00:35:00 * @author shingo-takahashi * * Copyright 2011-2014 TIDAコンソーシアム All Rights Reserved. */ package com.tida_okinawa.corona.correction.synonym; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.IProgressMonitor; import com.tida_okinawa.corona.correction.morphem.SyntaxStructure; import com.tida_okinawa.corona.io.model.MorphemeElement; import com.tida_okinawa.corona.io.model.dic.ICoronaDic; import com.tida_okinawa.corona.io.model.dic.IDicItem; import com.tida_okinawa.corona.io.model.dic.IFluc; import com.tida_okinawa.corona.io.model.dic.IFlucDic; import com.tida_okinawa.corona.io.model.dic.ISynonym; import com.tida_okinawa.corona.io.model.dic.ISynonymDic; import com.tida_okinawa.corona.io.model.dic.ITerm; /** * 同義語補正処理 * * @author imai * */ public class SynonymCorrector { /** * sub term の原形 -> main term のアイテムのマップ */ Map<String, ITerm> map = new HashMap<String, ITerm>(); /** * * @param dics * 同義語辞書のリスト */ public SynonymCorrector(List<ICoronaDic> dics) { } /** * 解析に必要な初期化を行う。<br /> * 初期化に失敗した場合、<code>monitor.setCanceled(true)</code>を呼び出し、初期化処理を中断する * * @param dics * 解析に使用する辞書 * @param monitor * 進捗表示ダイアログ */ public void init(List<ICoronaDic> dics, IProgressMonitor monitor) { if (dics.size() > 0) { monitor.beginTask("準備", dics.size()); monitor.setTaskName("辞書データ準備"); for (ICoronaDic dic : dics) { monitor.subTask(dic.getName()); if (dic instanceof ISynonymDic) { createMap((ISynonymDic) dic); } if (dic instanceof IFlucDic) { createMap((IFlucDic) dic); } monitor.worked(1); } monitor.done(); if (map.size() == 0) { monitor.setCanceled(true); } } else { monitor.setCanceled(true); } } /** * 同義語補正処理 * * 同義語形態素(Sub)を代表の形態素(Main)に置き換える * * @param text * 係り受け解析結果 * (テキスト) * @return 同義語を補正した係り受け解析結果 */ public SyntaxStructure process(String text) { SyntaxStructure ss = new SyntaxStructure(text); process(ss); return ss; } /** * 同義語補正処理 * * 同義語形態素(Sub)を代表の形態素(Main)に置き換える * * @param ss * 係り受け解析結果 - メソッド内で更新される */ public void process(SyntaxStructure ss) { process(ss.getMorphemeElemsnts()); } private void process(List<MorphemeElement> elements) { for (MorphemeElement element : elements) { process(element); } } private void process(MorphemeElement element) { String base = element.getGenkei(); ITerm main = map.get(base); int n = 0; while (main != null && n < 100) { element.replace(main); // 代表後が別の同義語のsubにある場合 base = main.getValue(); main = map.get(base); n++; } if (n >= 100) { // TODO: ここに出力するとユーザーに見えないけどどうする? System.err.println("infinite loop"); base = main.getValue(); for (Entry<String, ITerm> entry : map.entrySet()) { if (entry.getKey().equals(base)) { System.out.println(entry); } } } } private void createMap(ISynonymDic dic) { for (IDicItem item : dic.getItems()) { ISynonym synItem = (ISynonym) item; ITerm mainTerm = synItem.getMain(); if (mainTerm != null) { for (ITerm subTerm : synItem.getSub()) { if (subTerm != null) { if (subTerm.getValue().equals(mainTerm.getValue())) { System.err.println(dic.getName() + ": \"" + mainTerm.getValue() + "\" mainとsubが同じ"); } else { map.put(subTerm.getValue(), mainTerm); } } } } } } private void createMap(IFlucDic dic) { for (IDicItem item : dic.getItems()) { IFluc fluc = (IFluc) item; ITerm mainTerm = fluc.getMain(); if (mainTerm != null) { for (ITerm subTerm : fluc.getSub()) { if (subTerm != null) { if (subTerm.getValue().equals(mainTerm.getValue())) { System.err.println(dic.getName() + ": \"" + mainTerm.getValue() + "\" mainとsubが同じ"); } else { map.put(subTerm.getValue(), mainTerm); } } } } } } }