这个是好几年前写的了.都统一放到cnblogs上面.

--------------------------------Node ----------------------------------

package com;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @desc ac节点
* @date 2012-08-04
*
*/
public class Node {
private Map<String, Node> sons = new HashMap<String, Node>();
// 指向失败链
private Node fail;
private Node parent;
// 输出标志
private boolean out;
// 字符
private String val;

public void addSon(String val, Node son) {
sons.put(val, son);
}

public Map<String, Node> getSons() {
return sons;
}

public Node getFail() {
return fail;
}

public void setFail(Node fail) {
this.fail = fail;
}

public Node getParent() {
return parent;
}

public void setParent(Node parent) {
this.parent = parent;
}

public boolean isOut() {
return out;
}

public void setOut(boolean out) {
this.out = out;
}

public String getVal() {
return val;
}

public void setVal(String val) {
this.val = val;
}

public String toString() {

List<String> result = new ArrayList<String>();
result.add(this.getVal());
Node parent = this.getParent();
while (parent != null) {
result.add(parent.getVal());
parent = parent.getParent();
}
StringBuffer res = new StringBuffer();
for (int i = result.size() - 1; i >= 0; i--) {
res.append(result.get(i));
}

return res.toString();
}

}

-------------------------------------------------------------SearchTree --------------------------------

package com;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.sohu.fortune.talk.admin.util.ac.Node;

/**
* @desc 查找树
*
* AC 多模匹配 分为三步
* 1. 字典树的构造,
* 按照关键志生成一个查找树.
* 2.失败链的构造,
* 最大后缀表示,生成查找失败节点的下一跳(和kmp模式匹配差不多)
* 3.输出
*
*/
public class SearchTree {
// 跟节点
private Node root = new Node();
// 生成fail,遍历用
private List<String> keywords = new ArrayList<String>();

/**
* 添加关键词,生成一个查找树
*
* 1. 字典树的构造
* @param keyword
*/
public void add(String keyword) {
if (keyword == null || keyword.length() == 0) {
return;
}
keywords.add(keyword);
Node currNode = root;
for (int i = 0, j = keyword.length(); i < j; i++) {
char c = keyword.charAt(i);
String value = String.valueOf(c);
if (currNode.getSons().containsKey(value)) {
Node selectNode = currNode.getSons().get(value);
if (i == j - 1) {
selectNode.setOut(true);
}
currNode = selectNode;
} else {
Node sNode = new Node();
sNode.setVal(value);
sNode.setParent(currNode);
currNode.addSon(value, sNode);
if (i == j - 1) {
sNode.setOut(true);
}
currNode = sNode;
}
}

}

/**
* 失败链的构造
*/
public void buildFail() {

root.setFail(root);
for (String keyword : keywords) {
// 最大后缀表示
Node fail = root;
String prefix = "";
for (char c : keyword.toCharArray()) {
prefix += c;
Node currNode = searchNode(prefix);
String sval = String.valueOf(c);
if (fail.getSons().containsKey(sval)) {
if (fail.getSons().get(sval) != currNode) {
fail = fail.getSons().get(sval);
currNode.setFail(fail);
} else {
fail = root;
currNode.setFail(fail);
}

} else {
// 查找后缀,匹配最大
boolean hasfound = false;
for (int i = 1; i < prefix.length(); i++) {
String suffix = prefix.substring(i);
Node sufNode = searchNode(suffix);
if (sufNode != null) {
currNode.setFail(sufNode);
fail = sufNode;
hasfound = true;
break;
}
}
if (!hasfound) {
currNode.setFail(root);
fail = root;
}
}
}
}
}

/**
* 根据字符串 查找node
*
* @param keyword
* @return
*/
private Node searchNode(String keyword) {

if (keyword.length() == 1) {
return root.getSons().get(keyword);
} else {
Node tree = root.getSons().get(keyword.substring(0, 1));
for (int i = 1, j = keyword.length(); i < j; i++) {
char c = keyword.charAt(i);
String value = String.valueOf(c);

if (tree != null) {
if (tree.getSons().containsKey(value)) {
tree = tree.getSons().get(value);
} else {
return null;
}
} else {
return null;
}

}
return tree;
}
}

// 查找关键词
public Set<String> search(String exp, Set<String> levelSet) {

Node pathNode = root;
for (int i = 0, j = exp.length(); i < j; i++) {
char c = exp.charAt(i);
String value = String.valueOf(c);
if (pathNode.getSons().containsKey(value)) {
pathNode = pathNode.getSons().get(value);
if (pathNode.isOut()) {
levelSet.add("[" + pathNode.toString() + "]");
}
} else {
do {
if (pathNode.isOut()) {
if (pathNode.isOut()) {
levelSet.add("[" + pathNode.toString() + "]");
}
}
if (pathNode.getSons().containsKey(value)) {
pathNode = pathNode.getSons().get(value);
if (pathNode.isOut()) {
levelSet.add("[" + pathNode.toString() + "]");
}
break;
}
} while ((pathNode = pathNode.getFail()) != root);

if (pathNode == root) {
if (pathNode.getSons().containsKey(value)) {
pathNode = pathNode.getSons().get(value);
if (pathNode.isOut()) {
levelSet.add("[" + pathNode.toString() + "]");
}
}
}
}
}

return levelSet;
}

public Node getRoot() {
return root;
}

public static void main(String args[]) {

SearchTree tree = new SearchTree();

tree.add("ai.aaa");
tree.add("美国");
tree.add("ai.oa");
tree.add("ai.vcv5");
tree.add(".org");
// tree.add("baid.us");
tree.buildFail();
//
Set<String> res = new HashSet<String>();
System.out
.print(tree
.search(
"用来ai.aaa自美ai.aaa国ai.aaa的页岩.org气革命打压大秦不成立:1、中国埋藏3000米左右,远大于美国1000米;2、西煤东运2020年之前留有3500万吨缺口;3、美国的天然气发电成本低而我国高且缺少资源;4、美国2015年前不是停止发电使用煤,而是采取了碳发电新技术即煤气化发电;5、我国的电力需求总体上是增长趋势。",
res));

}
}

java实现多模匹配算法的更多相关文章

  1. 基于AC有限状态机的多模匹配算法

    参考链接:http://www.cnblogs.com/zzqcn/p/3525636.html 感谢原文作者. 花了两天半时间实现并测试了算法. 按照上文的思路实现了一遍,可能是原文中有些地方描述的 ...

  2. 多模匹配算法之Aho-Corasick

    除剔除那些含有敏感词的文本,由于有大量的敏感词,所以通过简单的正则表达式和字符串查找的方式效率太低,每次都有遍历一次字符串.而AC算法的核心思想就是避免不必要的回溯使搜索一直沿着向前的方向,最大可能的 ...

  3. Aho-Corasick算法、多模正则匹配、Snort入门学习

    希望解决的问题 . 在一些高流量.高IO的WAF中,是如何对规则库(POST.GET)中的字符串进行多正则匹配的,是单条轮询执行,还是多模式并发执行 . Snort是怎么组织.匹配高达上千条的正则规则 ...

  4. AC多模式匹配算法

    建议:学习ac算法最好的途径是看论文pdf_Efficient_String_Matching_An_Aid_to_Biblio 一.一般的搜索算法 keyword: { he, she, his, ...

  5. 【模式匹配】Aho-Corasick自动机

    1. 多模匹配 AC自动机(Aho-Corasick Automaton)是多模匹配算法的一种.所谓多模匹配,是指在字符串匹配中,模式串有多个.前面所介绍的KMP.BM为单模匹配,即模式串只有一个.假 ...

  6. Mysql Index、B Tree、B+ Tree、SQL Optimization

    catalog . 引言 . Mysql索引 . Mysql B/B+ Tree . Mysql SQL Optimization . MySQL Query Execution Process 1. ...

  7. AC自动机(转)

    http://www.cppblog.com/mythit/archive/2009/04/21/80633.html 首先简要介绍一下AC自动机:Aho-Corasick automation,该算 ...

  8. AC自动机算法详解

    首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...

  9. AC自动机算法详解 (转载)

    首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章, ...

随机推荐

  1. 工作vs.学�

    近一两年来,我先后对[工作与学习]的复杂过程有过多次的头脑风暴,而且感觉在这方面略有所成(看这里和这里):当然既然仅仅是头脑风暴,所谓的所成也仅仅是一些粗糙的想法,一些没有实证过的如果,算是积累而已, ...

  2. oc-03-OC访问OC源文件、C源文件中的函数

    show.h #ifndef __OCDay01__Show__ #define __OCDay01__Show__ #include <stdio.h> extern void test ...

  3. mysql 5.6 原生Online DDL解析

    http://seanlook.com/2016/05/24/mysql-online-ddl-concept/ 做MySQL的都知道,数据库操作里面,DDL操作(比如CREATE,DROP,ALTE ...

  4. [原创]经历:asp.net oracle 部署问题以及解决方法

    精简的美丽...... 一.环境    开发环境        win7 64bit         Vs2010        Oracle 11g r2 64bit        <inst ...

  5. TFS服务器(微软源代码管理服务器)上彻底删除项目

    在TFS服务器上建立了很多项目,发现在Team Explorer中,只能移除团队项目,这种移除,只是将项目从当前Team Explorer项目列表中删除,下一次Connect到TFS服务器时,或者刷新 ...

  6. apache配置--虚拟目录

    apache在httpd-vhosts.conf中 配置二级域名或者泛域名: <VirtualHost *:80>    ServerAdmin 846606478@qq.com    D ...

  7. C#文件操作系列(一)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  8. python(5) - 冒泡排序

    data = [10, 4, 33, 21, 54, 3, 8, 11, 5, 22, 2, 1, 17, 13] ''' 思路:有多少个元素就循环多少次,每次循环从第一个元素开始与它后面的元素比较, ...

  9. 关于js中event的target和currentTarget的区别

    今天又遇到这个问题了,总是搞不清楚target和currentTarget的区别,百度搜索的时候看到一遍文章解释得很清楚,特意记录下录,以备不时之需: target与currentTarget的区别? ...

  10. hdu 4000 树状数组

    思路:找出所有 a<b<c||a<c<b的情况,在找出所有的a<b<c的情况.他们相减剩下就是a<c<b的情况了. #include<iostre ...