Esempio n. 1
0
        /// <summary>
        /// 合并数量词
        /// </summary>
        /// <param name="list"></param>
        /// <param name="wordNet"></param>
        /// <param name="config"></param>
        protected void CombineNumQuant(List <Vertex> list, WordNet wordNet, SegConfig config)
        {
            if (list.Count < 4)
            {
                return;                     // 除去首尾辅助节点2个,还需要至少2个有效节点才能合并
            }
            var sb   = new StringBuilder();
            int line = 1;                   // 初始化为1,跳过起始辅助节点

            for (int i = 0; i < list.Count; i++)
            {
                var pre = list[i];
                if (pre.HasNature(Nature.m))     // 第一个数词出现
                {
                    sb.Append(pre.realWord);
                    Vertex cur = null;
                    i++;
                    while (i < list.Count)      // 遍历数词之后的词
                    {
                        cur = list[i];
                        if (cur.HasNature(Nature.m))        // 连续数词
                        {
                            sb.Append(cur.realWord);
                            list[i] = null;
                            RemoveFromWordNet(cur, wordNet, line, sb.Length);
                            i++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (cur != null)                                                                         // 合并连续的数词后,遇到的第一个非数词
                    {
                        if (cur.HasNature(Nature.q) || cur.HasNature(Nature.qv) || cur.HasNature(Nature.qt)) // cur 是量词
                        {
                            if (config.indexMode)                                                            // 如果开启索引(最小)分词模式,则先将连续数词作为一个节点添加进词网
                            {
                                wordNet.Add(line, new Vertex(sb.ToString(), new WordAttr(Nature.m)));
                            }

                            sb.Append(cur.realWord);        // 合数量词
                            list[i] = null;
                            RemoveFromWordNet(cur, wordNet, line, sb.Length);
                        }
                        else                                // 遇到第一个非数词,也非量词
                        {
                            line += cur.realWord.Length;    // 更新行号,表示跳过这个(非数非量)词
                        }
                    }

                    if (sb.Length != pre.realWord.Length)                                  // 长度不等,意味着合并到连续数词或者数量词
                    {
                        foreach (var vertex in wordNet.GetRow(line + pre.realWord.Length)) // 遍历第一个数词之后的行号上的所有节点列表,将这些节点的前驱节点置为空
                        {
                            vertex.from = null;
                        }
                        pre.realWord = sb.ToString();       // 首个数词修改为连续数词 或者 数量词
                        pre.word     = TAG_NUMBER;          // 实际上,本项目将数量词等同数词处理了
                        pre.attr     = new WordAttr(Nature.mq);
                        pre.wordId   = CoreDictionary.M_WORD_ID;
                        sb.Clear();
                    }
                }

                sb.Clear();
                line += pre.realWord.Length;            // 更新行号,跳过合并后的数量词
            }
        }