算法描述(正向):

  给定最大词长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. css3设置box-pack和box-align让div里面的元素垂直居中

    只要设置元素的box-pack和box-align即可,这两个属性当前只有webkit和moz支持,要设置垂直居中的话只需要将这两个属性的值都设置为center即可,需要的朋友可以参考下   以前处理 ...

  2. 自学SQL语言的例子(使用MySQL实现)

    SQL语言作为一种数据库管理的标准语言有着极为广泛的应用场景,菜鸟入门选用的数据库软件是轻量级的免费(这个极为重要)的MySQL,下载链接如下:http://www.mysql.com/downloa ...

  3. sql 去除结尾的回车或者换行

    CREATE FUNCTION REMOVE_ENTER (@DESC VARCHAR(8000))RETURNS VARCHAR(8000)ASBEGIN DECLARE @STR VARCHAR( ...

  4. Sql Server 列转行 Pivot使用

    今天正好做 数据展示,用到了列转行,行转列有多种方式,Pivot是其中的一种,Povit 是sql server 2005以后才出现的功能, 下面的业务场景: 每个月,进货渠道的总计数量[Total] ...

  5. Java SE基础部分——常用类库之Math和Random类(随机产生数值)

    //20160518 Math类常用方法 练习 package MyPackage; public class MathDemo {//定义主类和main方法 public static void m ...

  6. php simple_html_dom 一个iconv错误引起解析中断的问题,貌似内存溢出

    环境: $pageNum = 8; for ($i = 1; $i < $pageNum; $i++) { $html = new simple_html_dom(); $host = 'htt ...

  7. git 克隆本地仓库

    如果要从本地仓库克隆到另一个地方使用如下命令 git clone d:/SourceRepository d:/DestinationRepository d:/SourceRepository:本地 ...

  8. Qt 控件

    一.布局管理器 QHBoxLayout 水平布局 QVBoxLayout 垂直布局 QGridLayout 格点布局 QFormLayout 关联布局 QSplitter 分裂器 Spacers 间隔 ...

  9. 边缘检测之Sobel检测算子

    在讨论边缘算子之前,首先给出一些术语的定义: (1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像. (2)边缘点:图像中具有坐标[x,y],且处在 ...

  10. jquery解决onmouseover和onmouseout合用的bug问题

    经常会遇到鼠标放到一个元素上显示另外一个元素,这两个元素是父子关系,比如在A上绑定mouseover和mouseout事件来显示或隐藏B元素,A元素包含B元素,当鼠标移到B元素后浏览器认为你移开了A, ...