算法描述(正向):

  给定最大词长n,待分词文本str,指针f=0,词典dic文档

  1 取子串sub=str(f,f+n)

  2 如果(遍历dic,有匹配sub)  f++;

  3 否则  n--;

  4 注意:边界判定、没有找到词的情况

算法举例分析(正向):

  你有个要分词的文本“你毁了我容忍傻逼的能力”,你给出能最大接受的词长为6

(注意,6为6字节(byte),而一个汉字为2字节,你可能注意到下面的程序里我把6除以2了,因为在java里,char也是两字节的,所以它能装一个汉字,也可以装一个字母或符号。)

  现在指针指向第一个字,第一次取到的子串是“你毁了”,在词典中找有没有这个词,没有,那我们把词长变成4,即两个字,第二次取到的子串是“你毁”,再找,也没有,第三次取到的子串是“你”,在词典中能找到了,这时指针加一,指向“毁”字,词长恢复6,这就是一轮查找了。

  。。。

  跳过几步,假如现在指针指向了“容”字,第一次取到“容忍傻”,第二次取到“容忍”,“容忍”在词典能找到,这个时候,指针需要移动两位指向“傻”字,同理,若你取到三个字的词而且这个词能在词典中找到时,指针也要移三位,即 f+n

反向最大匹配跟正向原理一样,只是指针从最后一位开始向前移动。

 package Algorithm;

 import common.InitializeCorpus;
import java.io.IOException;
import java.util.Stack; /**
*
* @author 小振xzh 20140317
* 正向/反向最大匹配分词算法
*/
public final class MaximumMatching {
public String result; //结果
private int posIndex; //指针
private int len; //长度
private int maxLen; //最大长度
private boolean re; //false正向,true反向 //---正向---
public String forwardMaximumMatching(int maxLength, String str) throws IOException{
result = "";
posIndex = 0;
len = maxLength;
maxLen = len;
re = false;
MM(str, maxLen, 0);
return result;
} //---反向---
public String reversedMaximumMatching(int maxLength, String str) throws IOException{
result = "";
posIndex = 0;
len = maxLength;
maxLen = len;
re = true;
MM((new StringBuilder(str)).reverse().toString(), maxLen, 0); //源串反转
return result;
} public void MM(String source,int len,int frompos) throws IOException{
if(posIndex>source.length()-1){
return;
}
if(source.length()-frompos<len){
len = source.length()-frompos;
}
String tmp = source.substring(frompos, frompos+len); //获得子串 if(!re){
if(InitializeCorpus.ChineseDicList.contains(tmp)){ //这是另一个类里定义的静态ArrayList,里面存的是词
result += tmp+"/ ";
posIndex += len;
len = maxLen; //重置长度
MM(source, len, posIndex);
}else if(len>1){
len -= 1;
MM(source, len, posIndex);
}else{
result += "字典中没有‘"+tmp+"’字/ ";
posIndex += 1;
len = maxLen;
MM(source, len, posIndex);
}
}else{
tmp = (new StringBuilder(tmp)).reverse().toString();
Stack<String> sk = new Stack<String>(); //反向使用stack存储词语
if(InitializeCorpus.ChineseDicList.contains(tmp)){
sk.push(tmp+"/ ");
posIndex += len;
len = maxLen;
MM(source, len, posIndex);
}else if(len>1){
len -= 1;
MM(source, len, posIndex);
}else{
sk.push("字典中没有’"+tmp+"'字/ ");
posIndex += 1;
len = maxLen;
MM(source, len, posIndex);
}
while(!sk.isEmpty()){
result += sk.pop();
}
}
}
}

------------------2014年03月22日

关于算法的效率改进的一个地方,就是在构造函数中,把词典读到一个数组里,空间换时间,这样速度可以提高大约10倍?

-------------------2014年04月15日

修改了算法的代码 | 代码整洁之道

<正向/反向>最大匹配算法(Java)的更多相关文章

  1. 【05】Nginx:TCP / 正向 / 反向代理 / 负载均衡

    写在前面的话 在我们日常的工作中,不可能所有的服务都是简单的 HTML 静态网页,nginx 作为轻量级的 WEB 服务器,其实我们将它用于更多的地方还是作为我们网站的入口.不管你是后端接口,还是前端 ...

  2. SSH 正向/反向代理小记

    上周因为玩耍Minecraft的原因,折腾了下ssh的正向.反向代理,不得不说,科技改变命运..了解了基础的用法之后,很多跨域的事情都可以通过代理解决,而且只需要ssh帐号权限即可. 那么就简单来介绍 ...

  3. 《DNS的正向反向解析》RHEL6

    DNS的正向解析: Iptables –F Setenforce 0 安装DNS服务器的软件包: 启动DNS服务器: 修改DNS的配置文件:vim /etc/named.conf 修改DNS的配置:( ...

  4. MyEclipse 利用反向功能生成Java 实体类

    1.Window -> Open Perspective -> MyEclipse Database Explorer 到DB Broswer界面 2.右键 -> New,新建一个数 ...

  5. 03-UIKit、VC之间正向反向传值、代理

    目录: 一.正向传值 二.反向传值 三.代理模式 回到顶部 正向传值:就是把第一个界面的值传给第二个界面显示,其简单实现方法 1 首先在第一个界面中要有一个textField输入框,一个按钮butto ...

  6. POJ-1511 Invitation Cards---Dijkstra+队列优化+前向星正向反向存图

    题目链接: https://vjudge.net/problem/POJ-1511 题目大意: 给定节点数n,和边数m,边是单向边. 问从1节点出发到2,3,...n 这些节点路程和从从这些节点回来到 ...

  7. C# 算法之链表、双向链表以及正向反向遍历实现

    1.简介 链表是一种非常基础的数据结构之一,我们在日常开发种都会接触到或者是接触到相同类型的链表数据结构.所以本文会使用C#算法来实现一个简单的链表数据结构,并实现其中几个简单的api以供使用. 2. ...

  8. django 正向,反向

    表名 ,foreignkey, 正向 obj.表名小写_set.all() 反向操作.

  9. 使用netcat的正向 / 反向shell

    reverse shell bind shell reverse shell描述图: 在此示例中,目标使用端口4444反向连接攻击主机.-e选项将Bash shell发回攻击主机.请注意,我们也可以在 ...

随机推荐

  1. javaScript 工作必知(三) String .的方法从何而来?

    String 我们知道javascript 包括:number,string,boolean,null,undefined 基本类型和Object 类型. 在我的认知中,方法属性应该是对象才可以具有的 ...

  2. C# 类型的创建

    类 类是最普通的引用类型,最简单的声明如下所示: class YourNameClass { } 更复杂的类可以拥有以下这些选项: 置于关键字class前面的:属性(attributes)与class ...

  3. 对浏览器css兼容性的学习理解及问题解决汇总

    一.从浏览器内核的角度 来看,浏览器兼容性问题可分为以下三类: 1. 渲染相关:和样式相关的问题,即体现在布局效果上的问题. 2. 脚本相关:和脚本相关的问题,包括JavaScript和DOM.BOM ...

  4. Memcached管理

    安装memcached服务端: apt-get install memcached 配置文件存在于: /etc/memcached.conf 启动memcache: memcached -d -m - ...

  5. KVC和KVO

    OC中的一个比较有特色的知识点:KVC和KVO 一.KVC操作OC中的KVC操作就和Java中使用反射机制去访问类的private权限的变量,很暴力的,这样做就会破坏类的封装性,本来类中的的priva ...

  6. DEV控件自定义排序实现

    一般的控件或者组件都支持按照某一列进行排序.但是,这种排序是根据数据源里的数据默认按照降序或升序排序的,同时这样的排序与字段的类型有关. 假设现在字段的类型是字符串类型 ,但是,存储的数据时数字加一些 ...

  7. SVN多次重复验证

    在MyEclipse中使用svn checkout时,总是弹出密码验证信息,原因是在首次保存密码时与服务器的密码不一致,而每次都是读取的本地密码导致重复验证,这里我们可以删除本地 的密码信息,问题解除 ...

  8. day10_python学习笔记_chapter13_面向对象编程

    1. class NewClass(parent): def .... 如果没有父类, 则默认继承object类 2. 类属性访问(类似java中的静态属性和方法)直接用类名.属性名, 在python ...

  9. 【Howie玩docker】-使用mono编译c#程序

    根据前面的方法,在windows和Linux共享文件夹,然后就可以开发了! Start up an Ubuntu container $ docker run -it ubuntu bash Upda ...

  10. B2C 电商网站需要怎样的 ERP 系统

    B2C 电商网站需要怎样的 ERP 系统 主要由如下一些系统组成:1.进销存系统,你的产品的采供销当然最好是由系统来实现:2.BI系统,BI包括所有的流量.订单.商品.库存.发货等所有数据节点,亦包含 ...