(1)英文分词——波特词干提取算法

英文分词相比中文分词要简单得多,可以根据空格和标点符号来分词,然后对每一个单词进行词干还原和词形还原,去掉停用词和非英文内容。词干还原算法最经典的就是波特算法(Porter Algorithm官网http://tartarus.org/~martin/PorterStemmer/ )

Java版的波特词干提取算法代码如下:

import java.io.*;

/**
* 实现波特词干提取算法,将一个单词转换为它的原型。
*/
class PorterStemmer{

    private char[] b; /* 用来存待词干提取的单词(以char的形式) */
    private int i,     /* b中的元素位置(偏移量) */
            i_end, /* 要抽取词干单词的结束位置 */
            j, k;
    private static final int INC = 50;/* 随着b的大小增加数组要增长的长度(防止溢出) */

    public PorterStemmer(){
        b = new char[INC];
        i = 0;
        i_end = 0;
    }

    /**
     * 增加一个字符到要存放待处理的单词的数组。添加完字符时, 
     * 可以调用stem(void)方法来进行抽取词干的工作。
     * @param ch 字符
     */
    public void add(char ch){  
        if (i == b.length){
            char[] new_b = new char[i+INC];
            for (int c = 0; c < i; c++) new_b[c] = b[c];
            b = new_b;
        }
        b[i++] = ch;
    }

    /**
     * 增加字符数组ch到存放待处理的单词的数组b
     * @param ch 字符数组
     */
    public void add(char[] ch){
        add(ch,ch.length);
    }

    /**
     * 增加wLen长度的字符数组到存放待处理的单词的数组b。
     * @param w 字符数组
     * @param wLen 数组长度
     */
    public void add(char[] w, int wLen){
        if (i+wLen >= b.length){  
            char[] new_b = new char[i+wLen+INC];
            for (int c = 0; c < i; c++) new_b[c] = b[c];
            b = new_b;
       }
       for (int c = 0; c < wLen; c++) b[i++] = w[c];
    }

    /**
     * 返回单词的词干。
     */
    public String toString() { return new String(b,0,i_end); }

    /**
     * 返回单词的词干的长度
     */
    public int getResultLength() { return i_end; }

    /**
     * 返回单词的词干char[]
     */
    public char[] getResultBuffer() { return b; }

    /**
     * cons(i):参数i:int型;返回值bool型。当i为辅音时,返回真;否则为假
     * @param i b数组下标
     * @return cons(i) 为真 <=> b[i] 是一个辅音 
     */
    private final boolean cons(int i){  
        switch (b[i]){  
            case 'a': case 'e': case 'i': case 'o': case 'u': return false;
            //y开头,为辅;否则看i-1位,如果i-1位为辅,y为元,反之亦然。 
            case 'y': return (i==0) ? true : !cons(i-1);
            default: return true;
        }
    }

    /** 
    */
    /**
     * m():返回值:int型。表示单词b介于0和j之间辅音序列的个数。
     * 现假设c代表辅音序列,而v代表元音序列。<..>表示任意存在。于是有如下定义:
        <c><v>          结果为 0
        <c>vc<v>       结果为 1
        <c>vcvc<v>    结果为 2
        <c>vcvcvc<v> 结果为 3
        ....
     * @return 单词b介于0和j之间辅音序列的个数
     */
    private final int m(){  
        int n = 0;//辅音序列的个数,初始化
        int i = 0;//偏移量
        //<c>
        while(true){  
            if (i > j) return n;//如果超出最大偏移量,直接返回n
            if (!cons(i)) break; //如果是元音,中断
            i++;  //辅音移一位,直到元音的位置 
        }
        i++;//移完辅音,从元音的第一个字符开始 
        while(true){  //循环计算vc的个数 
            //<v>
            while(true){  //循环判断v  
                if (i > j) return n;
                if (cons(i)) break; //出现辅音则终止循环
                i++;
            }
            i++;
            n++;
            //<c>
            while(true){  //循环判断c 
                if (i > j) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值