下面的数据结构和方法用来组织候选词列表(即如何利用搜索结果):

class CCandidate
[m_BoneStart, m_BoneEnd)是这个候选词对应的bone区间;m_WordID是候选词对应的id;m_String是宽字节字符串的指针。通常 m_String就是m_WordID对应的宽字节字符串表示,但有时候选词并不在词表中(例如无效的拼音串儿)。
CIMIContext::getCandidates (bone, result):
如 果bone是尾节点,则直接返回。如果不是一个有效的pinyin Bone节点,将bone上的拼音string作为候选,放到result中,并返回。如果这个bone上有用户选择或最佳词,设置cp(候选词和评分 pair),将它保存在以word_id为索引的map中。

然后遍历[bone+1, T1]。对每个Bone节点,遍历其lexicon状态节点,找到起始节点为bone的状态节点(itlex-> m_BoneStart == bone),将pytrie上的词(如果不是拼音节点,则是Bone上的拼音字符串)加入到map中;遍历其lattice状态节点,如果该节点是从参数bone上转移而来的(its->m_pBackTraceNode->m_BoneAfter == bone),则将m_BackTraceWordId对应的候选词,加入到map中。最后,按评分(TCandiRank),对这个map进行堆排序,将排序后的结果保存在result中。

评分的原则是:首先列出用户选择的词,或者位于最佳路径上的词;优先列出从Lattice状态中得到的词;然后是Lexicon中的词。且词的长度越长,评分越高。
CIMIContext::getBestSentence(result, boneStart, boneEnd, original_format):
如果boneStart上没有最佳词,则向前(左)查找,直到某个存在最佳词的Bone,保存在realStart中。沿着最佳路径的这一段([realStart, boneEnd)),将最佳词添加到result中,记录期间有效拼音节点的个数,并返回。
下面的方法,和用户选择的设定和取消有关:

CIMIContext::cancelSelection(bone, update):
注 意,m_Skeleton上的最佳词(无论是用户选择还是计算确定)是前后相连的。从bone开始向左查找。如果某个Bone(记为uBone)的类型为 UserSelectedBestWord,则将其改为NoBestWordStartHere,设置found为true,退出循环;否则,如果该 Bone是计算确定的最佳词,则退出循环;否则,则继续向左查找,直到第一个Bone。如果found为true,且update参数为true, uBone开始搜索,并返回它;否则,因为无需搜索,直接返回参数bone。将[firstBone, bone]这个区间离bone最近的用户选择取消。
CIMIContext::cancelSelectionCover(bone, update):
这个方法和上面的类似,只是当参数bone的类型是最佳词时,直接返回。相当于将[firstBone, bone)这个区间离bone最近的用户选择取消。
CIMIContext::makeSelection(candi):
找到候选candi的起始Bone(m_BoneStart),调用cancelSelection()将其所处的用户选择取消(返回值为boneLeft),并将候选起始Bone的类型设置为UserSelectedBestWord,然后从boneLeft重新搜索。
我们下一回将以“经典风格”为例,介绍对User Editing(包括insertPinyin,erase,move cursor,selection等)的处理。
评论:

感謝您提供的詳細資訊!

发表于 廖宮毅 在 2007年10月13日, 06:27 下午 CST #

谢谢,看了很有帮助

发表于 林峰 在 2007年10月20日, 08:46 下午 CST #

发表一条评论:
该日志评论功能被禁用了。

This blog copyright 2009 by yongsun