/// <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; // 更新行号,跳过合并后的数量词 } }