这是我第一次写博客,里面有些内容可能描述不当,但是我能保证最后的程序可以在eclipse环境下运行

最近有了作业,要求写中文分词程序,主要是依据一个词典,txt文本,里面是词语,然后要求依据词典,对输入的一句话进行分词。txt的部分截图见下:

首先,要明确中文分词,需要包含的功能:

  1. 读取txt文件的数据
  2. 存储词语的容器,这里可以使用array,但是推荐使用set
  3. 具体中文分词的比对逻辑过程

首先读取txt文件,之前试了很多方式读取,但是最终效果不好,最后采用BufferedReader读取,并且存储在内存中。

这部分代码如下:

        StringBuffer buffer = new StringBuffer();
        BufferedReader bf= new BufferedReader(new FileReader("*****"));
            //*****为txt文件的路径,推荐使用绝对路径
		
        String s = null;        //定义并且赋初值
        while((s = bf.readLine())!=null)
        {//使用readLine方法,一次读一行
            buffer.append(s.trim());        //去掉s左右的空格并添加到buffer中
        }

        String xml = buffer.toString();    //将buffer中的数据转换为string并存到xml中
        bf.close();                        //关闭文件

现在我们得到了一个字符串xml,里面包含了txt文件中所有的数据,还有一大堆空格,,,

我们需要去掉这些空格,以提高检索效率,同时这个字符串不能直接检索,所以需要对其转换

通常情况下,可以把其转换为array,然后一一比对就行,但是注意上面的空格,转换后的array,包含很多空格(直接比对效率会低一些),所以需要去重,可以把那些空格去掉,当然了,还有其他方式去掉空格,百度会有一大堆。但是这里使用set另一个原因是,set的效率高。

set是一个集合,用于存储乱序数据,最大的特点就是没有重复的数据,也就没有索引,但是搜寻效率要比array高一些,它的常见方法见下表:

方法名用途
add()添加数据
clear()清空set
contains()判断set集合是否包含该参数
isEmpty()判断是否为空
iterator( )递归集合
remove( )去掉特定对象
size( ) 返回集合大小

这里我们需要用到contains()方法,括号里面的参数是用于判断set是否包含的元素。

在使用set之前,需要将其转换为array,来方便直接转换为set,这里我们采用分割split()方法,以空格分割,将得到结果直接转换为array。

这部分代码如下:

        String [] str=xml.split("\\s");		//以空格分割
//      System.out.println(str.length);		//输出数组的大小
        HashSet<String> set = new HashSet<>(Arrays.asList(str));	//将数组转换为set集合,去重
//      System.out.println(set.size());	//输出set中元素的个数

然后就是分词的索引结构了,简单概括一下逻辑,就是:

  1. 得到要分词的句子
  2. 将该句子代入set中,判断是都包含
  3. 如果包含直接结束了,不包含就去掉最后一个字符
  4. 将去掉字符的句子检索是否包含
  5. 循环3,4,直到set中包含子串并输出,如果子串只剩一个字符,那么就将这个字符输出
  6. 将句子去掉已经输出的子串,剩余的句子为一个新的句子,进行2,3,4,5,6,直到原句自全部输出

根据上面的逻辑结构,我们就可以得到下面的代码:

        String text="中华人民共和国是我的祖国,我爱五星红旗";
            //测试的句子
        int i=text.length();
        while(text.length()!=0)
        {
        	
        	
        	String a=text.substring(0, i);       //提取句子的一部分为一个子串
        	if(set.contains(a)==true)            //检索操作
        	{
        		System.out.println(a);
        		text=text.substring(i, text.length());        //去掉已经输出数据,其余组成一个新的text
        		i=text.length();
        	}
        	else
        	{
        		i--;               //检索set中没有包含,将句子从右向左推进一位
        	}
        	
        	if(a.length()==1)
        	{
        		System.out.println(a);        //如果子串中只有一个字符,就输出
        		text=text.substring(1, text.length());    //去掉已经输出数据,其余组成一个新的text
        		i=text.length();
        	}
        }

这样就可以完成整个分词操作,下面是分词程序的全部代码:

public static void main(String [] args) throws IOException
	{		
		StringBuffer buffer = new StringBuffer();
        BufferedReader bf= new BufferedReader(new FileReader("*****"));
		
        String s = null;
        while((s = bf.readLine())!=null)
        {//使用readLine方法,一次读一行
            buffer.append(s.trim());
        }

        String xml = buffer.toString();
        bf.close();
        String [] str=xml.split("\\s");		//以空格分割
//        System.out.println(str.length);		//输出数组的大小
        HashSet<String> set = new HashSet<>(Arrays.asList(str));	//将数组转换为set集合,去重
//        System.out.println(set.size());	//输出set中元素的个数
        String text="中华人民共和国是我的祖国,我爱五星红旗";
        int i=text.length();
        while(text.length()!=0)
        {
        	
        	
        	String a=text.substring(0, i);
        	if(set.contains(a)==true)
        	{
        		System.out.println(a);
        		text=text.substring(i, text.length());
        		i=text.length();
        	}
        	else
        	{
        		i--;
        	}
        	
        	if(a.length()==1)
        	{
        		System.out.println(a);
        		text=text.substring(1, text.length());
        		i=text.length();
        	}
        }
		
	}

具体注释可以看上面代码块。

如果有需要代码的,可以用下面的链接

链接:https://pan.baidu.com/s/1-V7VruEiUexcmEGbQYws5w 

提取码:xqur 

另外,我也将代码上传到csdn中了,这是地址,0积分哦!

https://download.csdn.net/download/qq_40142391/11139602

如果失效了,记得给我评论下,蟹蟹٩('ω')و

欢迎在评论区讨论相关问题,我很希望能得到各位的意见和看法

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐