HashMap实现中文分词器

HashMap简单实现的分词器

public class TokenizerDemo {

    private static Map<String, String> map = new HashMap<String, String>();

    //词典中最长词的长度,map中的key的最长长度
    private static final int maxSize = 3;
    static{
        //可以从数据库中加载或词表中加载
        map.put("中国", "");
        map.put("北京", "");
        map.put("中关村", "");
        map.put("海淀", "");
    }

    public static void main(String[] args) {
        String text = "中国人民共和国首都是北京,中关村在海淀区。";
        int length = text.length();
        for(int i=0; i<length; i++){
            int endIdx = i+maxSize;
            if(endIdx>length){
                endIdx = length;
            }
            //最大逆序匹配
            for(int j=0; j<maxSize; j++){
                String s = text.substring(i, endIdx);
                if(map.get(s)!=null){
                    //跳过匹配过的词(后面会说明跳过匹配词的原因)
                    i=endIdx-1;
                    System.out.println(s);
                    break;
                }else{
                    endIdx-=1;
                    if(endIdx==i){
                        break;
                    }
                }
            }
            
        }
    }
}

输出结果:
中国
北京
中关村
海淀

注意:
如果不跳过已经匹配的词会出现"北京剧院" 拆分成 [北京]、[京剧]、[剧院] 三个词,
如果跳过匹配过的词就会拆分成 [北京]、[剧院]。

分词原理:

从词典中找出最长词的长度,这里为maxSize=3,按照maxSize的长度从文本的第一位(i=0)截取要抽取的文本【中国人】,然后去Map中查找是否有对应的值,如果没有减去一个长度截取(maxSize-1)【中国】,去Map中查找,找到则停止当前查找,接着从匹配当前词后面的字(i=2)【人民共】开始继续上述的步骤开始查找。

代码执行的流程如下:

 第一次循环(i=0):
      中国人  -> 无命中(map中没找到)  (j=0)
      中国    -> map命中               (j=1)  【注释:命中后i+2(当前词)的长度。所以i=2】
 第二次循环(i=2):
      人民共  -> 无命中                (j=0)
      人民    -> 无命中                (j=1)
      人      -> 无命中                (j=2)
 第三次循环(i=3):
      民共和  -> 无命中                (j=0)
      民共    -> 无命中                (j=1)
      民      -> 无命中                (j=2)
 ...依次类推,找出文本中所有匹配词典中的词

很简单的代码就说明了分词器的原理(只是最简单、能命中词而以)。

应用场景

敏感词、文字过滤是一个网站必不可少的功能,可以使用这么简单的几行代码实现网站的敏感词过滤功能,自己这么简单几行代码就能实现是不是很棒。



作者:jijs
链接:https://www.jianshu.com/p/62f4a5596278
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值