下面的代码基于NFA算法实现了在多段字符串中匹配正则表达式,对比NFA算法可以看到它将pc由局部变量提升为类成员,以保存中间匹配状态,另外在匹配成功后将pc恢复到null状态。实际使用中,此类还应该增加一个"reset"方法,将pc值置为null,以便用户可以显式要求重新开始匹配。

public class MultiSegmentNFA {
private final Digraph G; // digraph of epsilon transitions
private final String regexp; // regular expression
private final int M; // number of characters in regular expression
private Bag pc = null;
public MultiSegmentNFA(String regexp) {
... // same as NFA
}
public boolean recognizes(String target) {
if (pc == null) {
DirectedDFS dfs = new DirectedDFS(G, 0);
pc = new Bag();
for (int v = 0; v < G.V(); v++)
if (dfs.marked(v))
pc.add(v);
}
for (int i = 0; i < target.length(); i++) {
Bag match = new Bag();
for (int v : pc) {
if (v == M)
continue;
if ((regexp.charAt(v) == target.charAt(i))
|| regexp.charAt(v) == '.')
match.add(v + 1);
}
DirectedDFS dfs = new DirectedDFS(G, match);
pc = new Bag();
for (int v = 0; v < G.V(); v++)
if (dfs.marked(v))
pc.add(v);
if (pc.size() == 0)
return false;
}
for (int v : pc)
if (v == M) {

 pc = null;
return true; }

return false;
}

public static void main(String[] args) {
LinkedList msgs = new LinkedList();
msgs.offer("welcome lonely logoout");
msgs.offer("to flog");
msgs.offer("into a fog");
String token = "outto"; // 这个目标由第1和第2个字符串拼接而成
String pat = "(." + token + ".)";
MultiSegmentNFA mnfa = new MultiSegmentNFA(pat);
String target = msgs.poll();
while (target != null) {
if (mnfa.recognizes(target)) {
break;
}
target = msgs.poll();
}
if (target == null) {
System.out.println("cannot find " + token + " in msgs.");
} else {
System.out.println("find pat in <" + target + ">");
}
}
}

Note: Java的Pattern类使用的就是基于NFA的搜索算法,见JDK 6文档java.util.regex.Pattern的"Comparison to Perl 5"一节。

能够进行多段文本匹配的NFA改良算法的更多相关文章

  1. 如何将一段文本编译成C#内存程序的过程

    string code = null; // 1. 生成要编译的代码.(示例为了简单直接从程序集内的资源中读取) Stream stram = typeof(CodeDOM).Assembly .Ge ...

  2. php 两段文本对比,不同的文字显示高亮

    php 两段文本对比,不同的文字显示高亮[下面这个只能区分错误后面的..]   <?php $str1 ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwgg ...

  3. python_计算一段文本各个字符的出现个数

    >题目要求 任意给定一段文本,求出每个字符出现的个数,并且打印出来 >程序实现 import pprint str01 = "重庆市,简称巴和渝,别称山城.渝都.雾都.桥都,中华 ...

  4. mysql 两张表字段模糊匹配--字符串拼接函数

    concat(A,B,C,...)  拼接字符串 例如concat('123','***','345')  =>123***345 SELECT concat( substr(t1.CODE, ...

  5. text matching(文本匹配) 相关资料总结

    最近工作上需要做句子语义去重相关的工作,本质上这是属于NLP中text matching(文本匹配)相关的内容.因此我花了一些时间整理了一些关于这个方向的资料,整理如下(也许会持续更新): BiMPM ...

  6. [Alg] 文本匹配-单模匹配与多模匹配

    实际场景: 网站的用户发了一些帖子S1, S2,...,网站就要审核一下这些帖子里有没有敏感词. 1. 如果网站想查一下帖子里有没有一个敏感词P,这个文本匹配要怎么做更快? 2. 如果网站想查一下帖子 ...

  7. [Alg] 文本匹配-单模匹配-KMP

    1. 暴力求解 如下图所示.蓝色的小三角表示和sequence比较时的开始字符,绿色小三角表示失败后模式串比对的开始字符,红色框表示当前比较的字符对. 当和模式串发生不匹配时,蓝色小三角后移一位,绿色 ...

  8. 跨模态语义关联对齐检索-图像文本匹配(Image-Text Matching)

    论文介绍:Negative-Aware Attention Framework for Image-Text Matching (基于负感知注意力的图文匹配,CVPR2022) 代码主页:https: ...

  9. 转:Xshell显示找不到匹配的outgoing encryption算法怎么办

    原文出处:http://www.xshellcn.com/xsh_column/suanfa-bpp.html 由用户反应在使用xshell和xftp连接debian 7时出现找不到匹配的outgoi ...

随机推荐

  1. 删除有序数组中的重复项II

    题目描述 给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素最多出现两次,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下 ...

  2. XML:xml常用注解

    @XmlRootelement 指定根目录. //标注在实体类上 @XmlRootElement(name = "xmlEntity") public class XmlEntit ...

  3. [小工具] chrome上日语翻译工具

    rikaikun -> 日语 "理解君" 下载地址: https://chrome.google.com/webstore/detail/rikaikun/jipdnfibh ...

  4. NodeJS 进程是如何退出的

    有几种因素可以导致 NodeJS 进程退出.在这些因素中,有些是可预防的,比如代码抛出了一个异常:有些是不可预防的,比如内存耗尽.process 这个全局变量是一个 Event Emitter 实例, ...

  5. WPF教程十一:简单了解并使用控件模板

    WPF教程十一:简单了解并使用控件模板 这一章梳理控件模板,每个WPF控件都设计成无外观的,但是行为设计上是不允许改变的,比如使用Button的控件时,按钮提供了能被点击的内容,那么自由的改变控件外观 ...

  6. 使用oss来存取及优化图片资源

    目录 1. 开通阿里云OSS,并创建存储空间 2. 图片上传及处理 2.1 图片上传 2.2 图片处理 前言: 在日常开发中,不免会遇到需要实现图片上传与展示的需求.比如一个文章发布系统,我们通常会开 ...

  7. python numpy 求数组的百位分数

    百分位数,统计学术语,如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数.运用在教育统计学中,例如表现测验成绩时,称PR值.分位数是以概率将一批数 ...

  8. python -- 结构数据类型(列表、元组、集合、字典)

    一.列表 列表表示一组有序的元素,这些元素可以是数字.字符串,也可以是另一个列表. # ----------------------------------------# 列表(list):一组有序的 ...

  9. Linux核心目录结构

    ------------恢复内容开始------------ 目录 含义及作用 /usr/bin 普通用户二进制命令目录 /usr/sbin root管理员用户使用的二进制命令目录 /boot 内核程 ...

  10. LC-322. 零钱兑换

    322. 零钱兑换 给你一个整数数组 coins ,表示不同面额的硬币:以及一个整数 amount ,表示总金额. 计算并返回可以凑成总金额所需的 最少的硬币个数 .如果没有任何一种硬币组合能组成总金 ...