/************************************ * file enc : AISCII * author : wuyanyi09@gmail.com ************************************/ #include "MPSegment.h" namespace CppJieba { MPSegment::MPSegment() { } MPSegment::~MPSegment() { } bool MPSegment::init(const char* const filePath) { if(!_trie.init()) { LogError("_trie.init failed."); return false; } LogInfo(string_format("_trie.loadDict(%s) start...", filePath)); if(!_trie.loadDict(filePath)) { LogError("_trie.loadDict faield."); return false; } LogInfo("_trie.loadDict end."); return true; } bool MPSegment::dispose() { return _trie.dispose(); } bool MPSegment::cut(const string& str, vector& res) { vector segWordInfos; if(!cut(str, segWordInfos)) { return false; } res.clear(); for(uint i = 0; i < segWordInfos.size(); i++) { res.push_back(TransCode::encode(segWordInfos[i].word.begin(), segWordInfos[i].word.end())); } return true; } bool MPSegment::cut(const string& str, vector& segWordInfos) { if(str.empty()) { return false; } segWordInfos.clear(); SegmentContext segContext; Unicode sentence; if(!TransCode::decode(str, sentence)) { LogError("TransCode::decode failed."); return false; } for(uint i = 0; i < sentence.size(); i++) { segContext.push_back(SegmentChar(sentence[i])); } //calc DAG if(!_calcDAG(segContext)) { LogError("_calcDAG failed."); return false; } if(!_calcDP(segContext)) { LogError("_calcDP failed."); return false; } if(!_cut(segContext, segWordInfos)) { LogError("_cut failed."); return false; } return true; } bool MPSegment::_calcDAG(SegmentContext& segContext) { if(segContext.empty()) { LogError("segContext empty."); return false; } Unicode unicode; for(uint i = 0; i < segContext.size(); i++) { unicode.clear(); for(uint j = i ; j < segContext.size(); j++) { unicode.push_back(segContext[j].uniCh); const TrieNodeInfo* pInfo = _trie.find(unicode); if(pInfo) { segContext[i].dag[j] = pInfo; } } if(segContext[i].dag.end() == segContext[i].dag.find(i)) { segContext[i].dag[i] = NULL; } } return true; //vector > vec; //Unicode::const_iterator beginIter = segContext.uintVec.begin(); //for(Unicode::const_iterator iterI = segContext.uintVec.begin(); iterI != segContext.uintVec.end(); iterI++) //{ // vec.clear(); // vec.push_back(pair(iterI - beginIter, NULL)); // for(Unicode::const_iterator iterJ = iterI + 1; iterJ != segContext.uintVec.end(); iterJ++) // { // //care: the iterJ exceed iterEnd // const TrieNodeInfo* ptNodeInfo = _trie.find(iterI, iterJ + 1); // if(NULL != ptNodeInfo) // { // vec.push_back(pair(iterJ - beginIter, ptNodeInfo)); // } // } // segContext.dag.push_back(vec); //} //return true; } bool MPSegment::_calcDP(SegmentContext& segContext) { if(segContext.empty()) { LogError("segContext empty"); return false; } for(int i = segContext.size() - 1; i >= 0; i--) { segContext[i].pInfo = NULL; segContext[i].weight = MIN_DOUBLE; for(DagType::const_iterator it = segContext[i].dag.begin(); it != segContext[i].dag.end(); it++) { uint nextPos = it->first; const TrieNodeInfo* p = it->second; double val = 0.0; if(nextPos + 1 < segContext.size()) { val += segContext[nextPos + 1].weight; } if(p) { val += p->logFreq; } else { val += _trie.getMinLogFreq(); } if(val > segContext[i].weight) { segContext[i].pInfo = p; segContext[i].weight = val; } } } return true; //segContext.dp.assign(segContext.uintVec.size() + 1, pair(NULL, 0.0)); //segContext.dp[segContext.uintVec.size()].first = NULL; //segContext.dp[segContext.uintVec.size()].second = 0.0; //for(int i = segContext.uintVec.size() - 1; i >= 0; i--) //{ // // calc max // segContext.dp[i].first = NULL; // segContext.dp[i].second = MIN_DOUBLE; // for(uint j = 0; j < segContext.dag[i].size(); j++) // { // const pair& p = segContext.dag[i][j]; // int pos = p.first; // double val = segContext.dp[pos+1].second; // if(NULL != p.second) // { // val += (p.second)->logFreq; // } // else // { // val += _trie.getMinLogFreq(); // } // if(val > segContext.dp[i].second) // { // segContext.dp[i].first = p.second; // segContext.dp[i].second = val; // } // } //} //segContext.dp.pop_back(); //return true; } bool MPSegment::_cut(SegmentContext& segContext, vector& res) { //if(segContext.dp.empty() || segContext.uintVec.empty() || segContext.dp.size() != segContext.uintVec.size()) //{ // LogFatal("dp or uintVec illegal!"); // return false; //} res.clear(); uint i = 0; while(i < segContext.size()) { const TrieNodeInfo* p = segContext[i].pInfo; if(p) { res.push_back(*p); i += p->word.size(); } else//single chinese word { TrieNodeInfo nodeInfo; nodeInfo.word.push_back(segContext[i].uniCh); nodeInfo.freq = 0; nodeInfo.logFreq = _trie.getMinLogFreq(); res.push_back(nodeInfo); i++; } } return true; } } #ifdef SEGMENT_UT using namespace CppJieba; int main() { MPSegment segment; segment.init(); if(!segment._loadSegDict("../dicts/segdict.gbk.v3.0")) { cerr<<"1"< res; string line; while(getline(ifile, line)) { res.clear(); segment.cut(line, res); PRINT_VECTOR(res); getchar(); } segment.dispose(); return 0; } #endif