模式匹配

Java编程的逻辑 (89) - 正则表达式 (中)

孤者浪人 提交于 2020-02-03 02:36:50
本系列文章经补充和完善,已修订整理成书《Java编程的逻辑》,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接 : http://item.jd.com/12299018.html 上节 介绍了正则表达式的语法,本节介绍相关的Java API。 正则表达式相关的类位于包java.util.regex下,有两个主要的类,一个是Pattern,另一个是Matcher。Pattern表示正则表达式对象,它与要处理的具体字符串无关。Matcher表示一个匹配,它将正则表达式应用于一个具体字符串,通过它对字符串进行处理。 字符串类String也是一个重要的类,我们在 29节 专门介绍过String,其中提到,它有一些方法,接受的参数不是普通的字符串,而是正则表达式。此外,正则表达式在Java中是需要先以字符串形式表示的。 下面,我们先来介绍如何表示正则表达式,然后探讨如何利用它实现一些常见的文本处理任务,包括切分、验证、查找、和替换。 表示正则表达式 转义符 '\' 正则表达式由元字符和普通字符组成,字符'\'是一个元字符,要在正则表达式中表示'\'本身,需要使用它转义,即'\\'。 在Java中,没有什么特殊的语法能直接表示正则表达式,需要用字符串表示,而在字符串中,'\'也是一个元字符,为了在字符串中表示正则表达式的'\'

从零开始的数据结构学习日记(八)——1.8串的简单模式匹配算法

安稳与你 提交于 2020-01-31 21:57:40
1.1简单的模式匹配算法 以下为顺序串的简单模式匹配算法,利用i和j记录当前的匹配位置,从目标串T的第pos个字符开始比较,若相等则比较后续的字符,若不相等则回溯到目标串的下一个字符开始与模式串的第一个字符比较。 int index ( seqstring * T , seqstring * p , int pos ) { i = pos ; j = 1 ; while ( i < T -> length && j < p -> length ) { if ( T -> ch [ i - 1 ] == p -> ch [ j - 1 ] ) { i ++ ; j ++ ; } else { i = i - j + 2 ; //主串回溯到这里 j = 1 ; } if ( j > p -> length ) { return ( i - p -> length ) ; } else return 0 ; } } 来源: CSDN 作者: The wind of freedom 链接: https://blog.csdn.net/sakaili/article/details/104122424

Rust macro开发新手入门

北慕城南 提交于 2020-01-31 17:45:50
Rust语言最强大的一个特点就是可以创建和利用宏/Macro。不过创建Rust宏看起来挺复杂,常常令刚接触Rust的开发者心生畏惧。这片文章的目的就是帮助你理解Rust Macro的基本运作原理,学习如何创建自己的Rust宏。 相关链接: 在线学编程 1、什么是Rust的宏/Macro? 如果你尝试过Rust,应该已经用过Rust的宏了: println! 。这个宏可以在终端输出一行文本,并且支持变量的插值。 简单地说,Rust宏让你可以发明自己的语法,编写出可以自行展开的代码,也就是我们通常所说的 元编程 ,你甚至可以用Rust宏来创作自己的DSL。 Rust宏的基本运作机制就是:首先匹配宏规则中定义的模式,然后将匹配结果绑定到变量,最后展开变量替换后的代码。 不理解也没有关系,让我们继续看。 2、如果创建Rust宏/Macro? 可以使用Rust预置的 macro_rules! 宏来创建一个新的Rust宏。 下图展示了如何创建一个空白的Rust宏: hey! ,这个宏什么功能也没有,我们现在只关注它的结构: () => {} 看起来很神秘,因为它不是标准的rust语法,是macro_rules!这个宏自己发明的,用来表示一条宏规则, => 左边是匹配模式,右边是等待展开的代码: 左边的小括号部分是Rust宏的匹配器/Matcher,用来匹配模式并捕捉变量

vim查找

给你一囗甜甜゛ 提交于 2020-01-31 09:24:27
本文摘自http://freetravel.blog.sohu.com/106769983.html VIM是被誉为非常高效的文本编辑软件。但是掌握并高效的使用是件有难度的事情。在VIM中进行快速的查找和替换是提高VIM使用效率的重要方法。下面是我在阅读VIM用户手册时整理的一些资料: 行内搜索。 f命令可以进行行内搜索。输入fx可以找到下一个x字符。 F命令可以在反方向进行行内搜索,输入Fx可以找到上一个x字符。 t命令同样是进行行内搜索,但是光标停留在符合条件的字符的前面。输入tx使光标停留在下一个x字符的前面。 T命令可以在反方向进行行内搜索,但是光标停留在符合条件的字符的下一个字符上。输入tx使光标停留在上一个x的后面的字符上。 %可以搜索与之匹配的对应的()[]{}。这个功能对于书写程序特别有用。 全文的搜索。键入/后,光标进入VIM底部的命令行,这时就可以输入以/为开始的/搜索命令了。 最简单的查找。输入/string就可以查找string字符串。 继续查找。在第一次搜索后输入n将会继续进行上一次搜索,如果输入3n那么会找到后面第三个符合的字符串。大写的N会在反方向,也就是向上进行搜索。 向上搜索。输入?可以向上搜索。随后的n命令将会继续向上搜索,N向下搜索,其他和/一样。 对大小写的匹配。 在命令行输入:set ignorecase可以设置搜索以忽略大小写的方式进行

Java编程思想学习笔记(13)

房东的猫 提交于 2020-01-29 03:58:27
Java编程思想学习笔记(13) 字符串 不可变String String对象是不可变的。查看JDK文档你就会发现,String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的 String对象则丝亳未动。 public class Immutable { public static String upcase(String s) { return s.toUpperCase(); } public static void main(String[] args) { String q = "howdy"; print(q); // howdy String qq = upcase(q); print(qq); // HOWDY print(q); // howdy } } 当把q传给upcaseo方法时,实际传递的是引用的一个拷贝。其实,每当把String对象作为方法 的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。 回到upcaseO的定义,传人其中的引用有了名字S,只有upcase()运行的时候,局部引用S才存在。一且upcase()运行结束,s就消失了。当然了,upcase()的返回值,其实只是最终结果的引用。这足以说明

弱势图解AC自动机

别说谁变了你拦得住时间么 提交于 2020-01-28 17:19:48
本篇文章主要详细介绍$AC$自动机的$fail$指针: 如果有什么不完善的地方,请联系我$qwq$ 前置知识: 1、建议学一下$kmp$算法 2、$Trie$ 导入: AC自动机是用来解决多模板匹配问题的,但是,如果就单纯的把每个模板串拼接在一起,或者单个单个匹配的话,肯定是会超时的,而它的思想是把所有的模式串建立一颗$Trie$,然后用文本串来匹配,那么我们就必须在这颗$Trie$树上进行快速跳转来优化,于是,AC自动机就诞生了 重点:fail指针到底是什么? 我们先来思考一个问题,假如我们按照上面的思想,把每一个模式串建立一颗字典树,那么怎样才能在这个模板串失配后快速跳到下一个有可能成功匹配的字符串来匹配呢?我们举个例子:假设文本串是$bcde$,模式串有两个,分别为$bce$和$cd$,我们为两个模式串建一颗$Trie$,如下图: 我们拿着文本串开始匹配,发现匹配到$2$节点后,就失配了,也就是模式串$bce$失配,那么我们如何快速跳到下一个模式串$cd$来匹配呢?这个时候你可能会说,到$0$节点开始匹配呀,可是这样其实就是重头匹配下一个字符串了,效率并不高,在这里,我们其实可以直接跳到$4$号节点开始匹配,为什么?那是因为我们发现$2$号节点是成功匹配了的,只是不能到$3$号节点去,但是我们发现$2$号节点匹配说明了字符$c$在文本串出现过,那么$c$必定会匹配,所以$0

洛谷P3375 【模板】KMP字符串匹配

China☆狼群 提交于 2020-01-28 04:56:49
题目传送门: 戳我进入 KMP算法是用来处理字符串匹配的问题的,也就是给你两个字符串,你需要回答B串是否是A串的子串,B串在A串中出现了几次,B串在A串中出现的位置等问题。 KMP算法的意义在于,如果你在洛谷上发了一些话,kkksc03就可以根据KMP算法查找你是否说了一些不和谐的字,并且屏蔽掉你的句子里的不和谐的话( 比如cxk鸡你太美就会被屏蔽成cxk**** ),还会根据你句子中出现不和谐的字眼的次数对你进行处罚 举个栗子:A:GCAKIOI B:GC ,那么我们称B串是A串的子串 我们称等待匹配的A串为主串,用来匹配的B串为模式串。 一般的朴素做法就是枚举B串的第一个字母在A串中出现的位置并判断是否适合,而这种做法的时间复杂度是O(mn)的,当你处理一篇较长文章的时候显然就会超时。 我们会发现在字符串匹配的过程中,绝大多数的尝试都会失败,那么有没有一种算法能够利用这些失败的信息呢? KMP算法就是 KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的 设主串(以下称为T) 设模式串(以下称为W) 用暴力算法匹配字符串过程中,我们会把T[0] 跟 W[0] 匹配,如果相同则匹配下一个字符,直到出现不相同的情况,此时我们会丢弃前面的匹配信息,然后把T[1] 跟 W[0]匹配,循环进行,直到主串结束,或者出现匹配成功的情况

KMP-单模式串匹配

◇◆丶佛笑我妖孽 提交于 2020-01-28 00:44:56
pat表示模式串,txt表示文本串,nex[i]表示pat中0~(i-1)最长相同前后缀。 KMP求pat在txt出现的次数或位置。 模式串的nex数组类似与ac自动机的fail指针,当发生不匹配时,跳到已匹配后缀最长的相同前缀的位置。求nex数组的过程就是pat自我匹配的过程。 学习链接:传送门   注意这个博客的预定约定和本文代码的约定不同 # include <iostream> # include <stdio.h> # include <string.h> using namespace std ; const int maxn = 1e6 + 7 ; char str [ maxn ] ; struct kmp { char pat [ maxn ] ; int pat_len ; int nex [ maxn ] ; void GetNext ( ) { int i = 0 , j = - 1 ; pat_len = strlen ( pat ) ; nex [ 0 ] = - 1 ; while ( i < pat_len ) { while ( j != - 1 && pat [ i ] != pat [ j ] ) j = nex [ j ] ; nex [ ++ i ] = ++ j ; } } int Count ( char * txt ) { //

[学习笔记]AC自动机

和自甴很熟 提交于 2020-01-27 21:57:06
AC自动机 Aho-Corasick automaton 本文基本上是oiwiki的复制粘贴: https://oi-wiki.org/string/ac-automaton/ 可能加上了自己感性理解 概述 AC 自动机是 以 TRIE 的结构为基础 ,结合 KMP 的思想 建立的 建立AC自动机有两个步骤: TRIE:将所有的模式串构成一颗字典树 KMP:对TRIE上所有的状态构造失配指针 可以说,AC自动机是由字典树和失配指针构成的 回顾KMP KMP匹配算法可以在线性时间内判定字符串 \(A[1-N]\) 是字符串 \(B[1-M]\) 的子串,并求出字符串A在字符串B中各次出现的位置.有两个数组: \(next,f​\) \(next[i]​\) 表示的是 A中以i为结尾的非前缀子串 与 A的前缀 能够匹配的最长 长度 \(f[i]​\) 表示的是 B中以i为结尾的子串 与 A的前缀 能够匹配的最长 长度 一直说AC自动机就是树上的KMP,那这两者有什么关系呢? 字典树 insert() 字典树上的每个节点代表有限自动机一个状态,表示的是某个模式串的前缀。 编译原理学得超级差..( 模式串的结尾状态被称为 可接受状态 字典树的插入: void insert(char *s){ int u=0; for(int i=1;s[i];++i){ if(!tr[u][s[i]-'a

.NET正则表达式入门金典

好久不见. 提交于 2020-01-27 13:12:16
在探讨这个话题之前,咱们先通过一个例子来看下为什么需要正则表达式? 先来看下面一个例子,解析如下IP: 192.160.1.234[port=8080,type=ftp] 将上述表达式中的IP地址,端口号和端口类型提取出来。 没有正则表达式之前,大家猛的一看,估计崩溃了。没办法,用string类的方法截取呗。于是,我们写下了如下代码: string str = "192.160.1.234[port=8080,type=ftp]"; int indexIP = str.IndexOf("["); string ip = str.Substring(0, indexIP); //获取端口号 int serverestart = str.IndexOf("="); int serverend=str.IndexOf(","); string server = str.Substring(serverestart+1,serverend-serverestart-1); //提取协议类型 int typestart = str.LastIndexOf("="); int typeend = str.LastIndexOf("]"); string type = str.Substring(typestart+1,typeend-typestart-1); string result =