Esempio n. 1
0
        /// <summary>
        /// 原子分词,连续的数字或连续的英文字母整体作为一格词,其他单个字符自成一词
        /// 没有标记词性
        /// </summary>
        /// <param name="sentence"></param>
        /// <returns></returns>
        public static List <string> AtomSeg(char[] sentence)
        {
            var list    = new List <string>(sentence.Length);
            var lastIdx = sentence.Length - 1;                  // 最后一个字符的下标
            var sb      = new StringBuilder();                  // 缓存连续的数字,或连续的英文字母

            char c;

            for (int i = 0; i < sentence.Length; i++)
            {
                c = sentence[i];
                if (c >= '0' && c <= '9')
                {
                    sb.Append(c);
                    if (i == lastIdx)
                    {
                        list.Add(sb.ToString());
                        sb.Clear();
                        break;
                    }
                    c = sentence[++i];
                    while (c == '.' || c == '%' || (c >= '0' && c <= '9'))       // 检查是否有连续的数字
                    {
                        sb.Append(c);
                        if (i == lastIdx)
                        {
                            list.Add(sb.ToString());
                            sb.Clear();
                            goto FINISH;
                        }
                        c = sentence[++i];
                    }
                    list.Add(sb.ToString());
                    sb.Clear();
                    i--;                            // 遇到非数字字符,需要回退一格,准备进入下一个for loop
                }
                else if (CharUtil.IsEnglishChar(c)) // 为啥这里不将空格并入英文字符里面呢?马萨卡... 用空格来分隔英文单词?
                {
                    sb.Append(c);
                    if (i == lastIdx)
                    {
                        list.Add(sb.ToString());
                        sb.Clear();
                        break;
                    }
                    c = sentence[++i];
                    while (CharUtil.IsEnglishChar(c))
                    {
                        sb.Append(c);
                        if (i == lastIdx)
                        {
                            list.Add(sb.ToString());
                            sb.Clear();
                            goto FINISH;
                        }
                        c = sentence[++i];
                    }
                    list.Add(sb.ToString());
                    sb.Clear();
                    i--;                        // 遇到非英文字母,需要回退一格,进入下一个for loop
                }
                else
                {
                    list.Add(c.ToString());
                }
            }
FINISH:
            return(list);
        }
Esempio n. 2
0
        /// <summary>
        /// 原子分词,连续的数字或者连续的英文空格作为一个整体词,其他单个字符自成一词
        /// 第一列为词性,第二列为原子分词后的词
        /// </summary>
        /// <param name="sentence"></param>
        /// <returns></returns>
        public static string[][] AtomSeg2Table(char[] sentence)
        {
            var table = new string[sentence.Length][];

            // 是否可以table类型从交叉数组改为二维数组
            for (int i = 0; i < sentence.Length; i++)
            {
                table[i] = new string[3];               //! 设置长度为 3,fst 为词性,snd为词本身,thd用于存储使用CRFModel Tag标注后的标签
            }
            int size    = 0;                            // 原子分词后的词数量,由于连续的数字被认为是一个整体,所以 size <= sentence.Length
            int lastIdx = sentence.Length - 1;          // 最后的位置下标
            var sb      = new StringBuilder();          // 缓存连续的(阿拉伯)数字

            for (int i = 0; i < sentence.Length; i++)
            {
                if (sentence[i] >= '0' && sentence[i] <= '9')
                {
                    sb.Append(sentence[i]);
                    if (i == lastIdx)                   // 如果当前已经是最后一个字符
                    {
                        table[size][0] = "M";           //? 词性?
                        table[size][1] = sb.ToString();
                        ++size;
                        sb.Clear();                     // 缓存结束
                        break;                          // 到达最后一个字符后退出for循环
                    }

                    char c = sentence[++i];                                // 到这里,说明当前字符是数字且尚未达到最后一个字符,则需要继续查看下一个字符是否是数字
                    while (c == '.' || c == '%' || (c >= '0' && c <= '9')) // 满足条件,表示连续的数值
                    {
                        sb.Append(c);
                        if (i == lastIdx)                   // 检测是否是最后一个字符
                        {
                            table[size][0] = "M";           //? 词性?
                            table[size][1] = sb.ToString();
                            ++size;
                            sb.Clear();                     // 缓存结束
                            goto FINISH;                    // 到达最后一个字符后退出for循环
                        }

                        c = sentence[++i];                 // 当前不是最后一个字符,则需要继续向后获取字符,以查看是否是数字
                    }

                    // 当前字符 c 已经不是数字字符了,此时需要处理缓存的连续数字字符串
                    table[size][0] = "M";
                    table[size][1] = sb.ToString();
                    ++size;
                    sb.Clear();
                    --i;                                    // 当前字符c 不是数字字符,进入下一个for循环处理,于是,需要将 i 回退一格
                }
                // 当前字符不是数字字符
                else if (CharUtil.IsEnglishChar(sentence[i]) || sentence[i] == ' ')      // 与数字字符处理类似,连续的英文or空格作为一个整体
                {
                    sb.Append(sentence[i]);
                    if (i == lastIdx)
                    {
                        table[size][0] = "W";
                        table[size][1] = sb.ToString();
                        ++size;
                        sb.Clear();
                        break;
                    }
                    char c = sentence[++i];
                    while (CharUtil.IsEnglishChar(c) || c == ' ')
                    {
                        sb.Append(sentence[i]);
                        if (i == lastIdx)
                        {
                            table[size][0] = "W";
                            table[size][1] = sb.ToString();
                            ++size;
                            sb.Clear();
                            goto FINISH;
                        }
                        c = sentence[++i];
                    }
                    table[size][0] = "W";
                    table[size][1] = sb.ToString();
                    ++size;
                    sb.Clear();
                    i--;
                }
                else
                {
                    table[size][0] = table[size][1] = sentence[i].ToString();
                    size++;
                }
            }
FINISH:
            if (size < sentence.Length)
            {
                return(ResizeArray(table, size));
            }
            return(table);
        }