<正向/反向>最大匹配算法(Java)
算法描述(正向):
给定最大词长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)的更多相关文章
- 【05】Nginx:TCP / 正向 / 反向代理 / 负载均衡
写在前面的话 在我们日常的工作中,不可能所有的服务都是简单的 HTML 静态网页,nginx 作为轻量级的 WEB 服务器,其实我们将它用于更多的地方还是作为我们网站的入口.不管你是后端接口,还是前端 ...
- SSH 正向/反向代理小记
上周因为玩耍Minecraft的原因,折腾了下ssh的正向.反向代理,不得不说,科技改变命运..了解了基础的用法之后,很多跨域的事情都可以通过代理解决,而且只需要ssh帐号权限即可. 那么就简单来介绍 ...
- 《DNS的正向反向解析》RHEL6
DNS的正向解析: Iptables –F Setenforce 0 安装DNS服务器的软件包: 启动DNS服务器: 修改DNS的配置文件:vim /etc/named.conf 修改DNS的配置:( ...
- MyEclipse 利用反向功能生成Java 实体类
1.Window -> Open Perspective -> MyEclipse Database Explorer 到DB Broswer界面 2.右键 -> New,新建一个数 ...
- 03-UIKit、VC之间正向反向传值、代理
目录: 一.正向传值 二.反向传值 三.代理模式 回到顶部 正向传值:就是把第一个界面的值传给第二个界面显示,其简单实现方法 1 首先在第一个界面中要有一个textField输入框,一个按钮butto ...
- POJ-1511 Invitation Cards---Dijkstra+队列优化+前向星正向反向存图
题目链接: https://vjudge.net/problem/POJ-1511 题目大意: 给定节点数n,和边数m,边是单向边. 问从1节点出发到2,3,...n 这些节点路程和从从这些节点回来到 ...
- C# 算法之链表、双向链表以及正向反向遍历实现
1.简介 链表是一种非常基础的数据结构之一,我们在日常开发种都会接触到或者是接触到相同类型的链表数据结构.所以本文会使用C#算法来实现一个简单的链表数据结构,并实现其中几个简单的api以供使用. 2. ...
- django 正向,反向
表名 ,foreignkey, 正向 obj.表名小写_set.all() 反向操作.
- 使用netcat的正向 / 反向shell
reverse shell bind shell reverse shell描述图: 在此示例中,目标使用端口4444反向连接攻击主机.-e选项将Bash shell发回攻击主机.请注意,我们也可以在 ...
随机推荐
- OC中的代理模式
OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的.这里举一个简单的例子:小孩类,护士类,保姆类,其中小孩类有两个方法 ...
- WPF子界面向父界面传递带参数的委托
需求如下: 父界面上有几个按钮,需要在点击按钮的时候向父界面传值,以知道该控制哪个界面显示. 父界面:WIN1 子界面:WIN2 此处或者说是子控件向父控件传值 1.子界面定义委托 WIN2里写: p ...
- EC读书笔记系列之9:条款16、17
条款16 成对使用new和delete时要采取相同形式 记住: ★若你在new表达式中使用[ ],必须在相应的delete中也使用[ ],反之亦然 -------------------------- ...
- C#获得命令提示符输出
原文:http://blog.csdn.net/abrahu/article/details/6611504 C#获得命令提示符输出 分类: c#应用程序2011-07-16 23:34 600人阅读 ...
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )
树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...
- 浅谈C中的指针和数组(六)
数组和指针,原本不想在写了,觉得这部分差不多了,但是自己在写程序的时候还是发现了一个错误.首先说一下我的要求: 给一个函数传递一个二维数组,然后我想在这个函数里面计算这个数组的行数. 写个类似的错误D ...
- markdown流程图
markdown流程图 markdown流程图 markdown流程图语法:https://github.com/adrai/flowchart.js 定义元素阶段的语法是 tag=>type: ...
- Some good questions
(一)#include <stdio.h>#include <stdlib.h>void getmemory(char *p){ p=(char *) malloc(100); ...
- Python中进行Base64编码和解码
Base64编码 广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容 ...
- docker exec 运行命令
docker:/root/sbin# docker exec -it 17aaf60ee3a1 /sbin/ifconfig -a eth1 Link encap:Ethernet HWaddr 22 ...