第八章柔性字符串匹配3

合集下载

C++课程设计之string字符串类

C++课程设计之string字符串类

课程名称: C++程序设计课程代码:05题目: 字符串类的设计年级/专业/班: 软件工程2班学生姓名:学号:指导教师: 袁辉勇开题时间: 2011 年 5 月 15 日完成时间: 2011 年 6 月 5 日—湖南人文科技学院计算机系目录一引言 (3)二设计目的与任务 (3)三设计方案 (4)1 总体设计 (4)2 详细设计 (4)四程序清单 (4)五程序调试与体会 (10)六运行结果 (14)七结论................................................. 错误!未定义书签。

八参考文献............................................... 错误!未定义书签。

摘要本设计通过定义字符串类来实现对字符串的赋值、连接、复制、查找、交换操作。

首先定义一个字符串类,通过调用字符串类中成员函数,对字符串类进行赋值,然后实现了字符串类之间的连接,字符串类之间的相互复制,字符串类之间的交换,最后可以对该字符串类中的字符串进行查找。

关键字:字符串;类;成员函数;对象AbstractBy defining the design of this type of string to string to the realization of the assignment, to connect, copy, find, exchange operations. First of all, the definition of a type of string, by calling members of the String class function, the type of string for assignment, and then realized the connection between the type of string, string-type between the copy, between string-type In exchange, the last class to the string of string to find.Keywords: string; category; members of the function; object 。

使用正则表达式进行字符串匹配和替换

使用正则表达式进行字符串匹配和替换

使用正则表达式进行字符串匹配和替换正则表达式是一种强大的工具,用于在字符串中进行匹配、查找和替换操作。

它通过定义一个模式来描述我们希望匹配的字符串的特征,然后再用这个模式去搜索和替换目标字符串。

在Python中,我们可以使用re模块来处理正则表达式操作。

下面将介绍一些常用的正则表达式匹配和替换操作。

1.匹配字符串中的数字:在正则表达式中,可以使用\d表示任意一个数字。

如果希望匹配多个数字,可以使用\d+表示多个数字。

例如,假设我们有一个字符串"abc123def456",希望匹配其中的数字部分,可以使用以下代码:```pythonimport restring = "abc123def456"pattern = "\d+"result = re.findall(pattern, string)print(result)```输出结果为['123', '456']。

2.匹配字符串中的字母:在正则表达式中,可以使用\w表示任意一个字母或数字(包括下划线)。

如果只希望匹配字母,可以使用[a-zA-Z]表示。

例如,假设我们有一个字符串"abc123def456",希望匹配其中的字母部分,可以使用以下代码:```pythonimport restring = "abc123def456"pattern = "[a-zA-Z]+"result = re.findall(pattern, string)```输出结果为['abc', 'def']。

3.匹配字符串中的特定字符:在正则表达式中,可以使用[]表示一个字符集合,可以匹配集合中的任意一个字符。

例如,[abc]匹配"a"、"b"或"c"。

匹配字符串有哪三个主要的方法

匹配字符串有哪三个主要的方法

匹配字符串有哪三个主要的方法
在编程中,有许多方法可以用来匹配字符串。

以下是三个主要的方法:
1. 字符串比较:这是最基本的方法,通过比较两个字符串是否相等来进行匹配。

您可以使用相等运算符(==)或字符串比较函数来实现。

这种方法适用于简单的匹配需求,例如判断一个字符串是否与给定的模式字符串完全匹配。

2. 正则表达式:正则表达式是一种强大的字符串匹配工具,可以通过定义模式来匹配和搜索符合特定规则的字符串。

正则表达式提供了一种灵活的方式来处理复杂的匹配需求,例如查找特定模式的字符串、提取数据等。

3. 字符串查找算法:字符串查找算法是一种高效的方法,用于在一个字符串中查找另一个字符串或模式的位置。

常用的字符串查找算法包括暴力匹配算法、Knuth-Morris-Pratt(KMP)算法、Boyer-Moore算法等。

这些算法在处理大规模文本搜索和替换时表现出色。

这些方法各有优缺点,您可以根据具体的需求选择适合的方法。

字符串匹配度算法

字符串匹配度算法

字符串匹配度算法字符串匹配度算法是计算两个字符串之间相似程度的一种算法。

在信息检索、文本分类、推荐系统等领域广泛应用。

它通过计算字符串之间的相似度来判断它们之间的关系,从而方便我们进行各种文本处理和分析工作。

字符串匹配度算法的核心思想是将字符串转换为向量表示,然后通过比较向量之间的距离或相似度来衡量字符串之间的相似程度。

常用的字符串匹配度算法有编辑距离算法、余弦相似度算法、Jaccard相似度算法等。

编辑距离算法是最常见的字符串匹配度算法之一,它衡量两个字符串之间的差异程度。

编辑距离算法将两个字符串进行插入、删除和替换操作,使它们变得相同。

通过计算进行了多少次操作,就可以得到它们之间的编辑距离。

编辑距离越小,表示两个字符串越相似。

余弦相似度算法是一种常用的基于向量的字符串匹配度算法。

它将字符串转换为向量表示,然后计算它们之间的夹角余弦值。

夹角余弦值越接近于1,表示两个字符串越相似;越接近于0,表示两个字符串越不相似。

Jaccard相似度算法是一种用于计算集合之间相似度的算法,也可以用于衡量字符串之间的相似度。

Jaccard相似度算法将字符串看作是字符的集合,然后计算它们之间的共同元素比例。

共同元素比例越高,表示两个字符串越相似。

除了这些常用的字符串匹配度算法外,还有很多其他的算法可以用于字符串的相似性比较。

不同的算法适用于不同的场景和需求,我们可以根据具体情况选择合适的算法。

总的来说,字符串匹配度算法是一种十分重要的工具,它可以帮助我们理解和处理文本数据。

在实际应用中,我们可以根据具体的需求选择合适的算法,从而完成各种文本处理和分析任务。

通过深入研究和应用这些算法,我们可以提高信息检索的准确性,加快文本处理的速度,提升推荐系统的效果。

希望大家能够重视字符串匹配度算法的研究和应用,为解决实际问题做出更多贡献。

python字符串匹配算法

python字符串匹配算法

python字符串匹配算法一、引言在计算机科学中,字符串匹配是指在文本中查找特定模式的子串。

这种操作在很多实际应用中都非常重要,例如在文件搜索、数据过滤、自然语言处理等领域。

Python提供了一些内置函数和库,可以方便地进行字符串匹配。

二、基本算法1. 朴素字符串匹配算法(Naive String Matching):这是一种简单的字符串匹配算法,通过遍历文本串,逐个字符地与模式串进行比较,以确定是否存在匹配。

2. 暴力匹配算法(Brute Force):这是一种基于字符比较的字符串匹配算法,通过逐个字符地比较文本串和模式串,直到找到匹配或者遍历完整个文本串为止。

3. KMP算法(Knuth-Morris-Pratt Algorithm):这是一种高效的字符串匹配算法,通过记忆已经比较过的字符,减少不必要的重复比较,从而提高匹配速度。

三、Python实现1. 朴素字符串匹配算法:在Python中,可以使用`str.find()`方法或`str.index()`方法来查找模式串在文本串中的位置。

示例如下:```pythontext = "Hello, world!"pattern = "world"index = text.find(pattern)if index != -1:print("Pattern found at index", index)else:print("Pattern not found")```2. 暴力匹配算法:在Python中,可以使用`re`模块来实现暴力匹配算法。

示例如下:```pythonimport retext = "Hello, world! This is a test."pattern = "world"matches = re.findall(pattern, text)if matches:print("Pattern found in text")else:print("Pattern not found in text")```3. KMP算法:在Python中,可以使用`re`模块中的`search()`方法来实现KMP算法。

字符串匹配实验

字符串匹配实验

微机原理实验字符串匹配实验一、实验目的(1)掌握提示信息的使用方法及键盘输入信息的方法。

(2)进一步熟悉在PC机上建立、汇编、连接、调试和运行汇编语言程序的过程。

二、实验要求根据提示信息,从键盘输入两个字符串,实现两个字符串的比较。

如两个字符串中有一个字符相同,则显示“MATCH”,否则显示“NO MA TCH”.三、实验程序框图本实验程序如图所示:Array四、参考程序CRLF MACROMOV AH ,02HMOV DL,0DHINT 21HMOV AH,02HMOV DL,0AHINT 21HENDMDATA SEGMENTMESS1 DB’MATCH’,0DH,0AH,’$’MESS2 DB’NO MA TCH’,0DH,0AH,’MAXLEN1 DB 81ACTLEN1 DB ?STRING1 DB 81 DUP(?)MAXLEN2 DB 81ACTLEN2 DB?STRING2 DB 81 DUP(?)DATA ENDSSTACK SEGMENT STACKSTA DB 50 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS: CODE,DS:DA TA,ES:DATA,SS:STACK START: MOV AX,DA TAMOV DS,AXMOV ES,AXMOV AX,STACKMOV SS,AXMOV SP,TOPMOV AH,09HMOV DX,OFFSET MESS3INT 21HCRLFMOV AH,0AHMOV DX,OFFSET MAXLEN1INT 21HCRLFMOV AH,09HMOV DX,OFFSET MESS4INT 21HMOV AX,0AHMOV DX,OFFSET MAXLEN2INT 21HCRLFCLDMOV SI,OFFSET STRING1MOV CL,[SI-1]MOV CH,00HKKK: MOV DI,OFFSET STRING2 PUSH CXMOV CL,[DI-1]MOV CH,00HMOV AL,[SI]MOV DX,DIREPNZ SCASBJZ GGGINC SIPOP CXLOOP KKKMOV AH,09HMOV DX,OFFSET MESS2INT 21HJMP PPPGGG: MOV AH,09HMOV DX,OFFSET MESS1INT 21HPPP: MOV AX,4C00HINT 21HCODE ENDSEND START。

字符串匹配问题的算法步骤

字符串匹配问题的算法步骤字符串匹配是计算机科学中常见的问题,主要用于确定一个字符串是否包含另一个字符串。

解决这个问题的算法可以分为暴力匹配算法、Knuth-Morris-Pratt(KMP)算法和Boyer-Moore(BM)算法等。

暴力匹配算法是最简单的一种方法。

它的基本思想是从主串的第一个字符开始,依次和模式串的每个字符进行比较,直到找到一个字符不匹配为止。

如果找到了不匹配的字符,则将主串的指针后移一位,重新开始匹配。

如果匹配成功,模式串的指针向后移一位,主串的指针也向后移一位,继续匹配。

这个过程一直进行下去,直到模式串的指针到达模式串的末尾,或者找到了一个匹配的子串。

尽管暴力匹配算法很简单,但是它的时间复杂度较高,为O(m*n),其中m是主串的长度,n是模式串的长度。

当主串和模式串很长时,暴力匹配算法的效率就会很低。

为了提高字符串匹配的效率,有很多其他的算法被提出。

其中比较著名的是KMP算法和BM算法。

KMP算法的核心思想是,当发生不匹配的情况时,不需要回溯主串的指针,而是通过已经匹配的部分字符的信息,将模式串的指针移动到一个新的位置,从而避免了不必要的比较。

具体来说,KMP算法在匹配的过程中,通过建立一个部分匹配表(Partial Match Table),来记录模式串中每个位置的最长前缀后缀的长度。

当发生不匹配的情况时,根据部分匹配表的信息,可以将模式串的指针直接移动到下一个可能匹配的位置。

BM算法是一种基于启发式的匹配算法,它的核心思想是从模式串的尾部开始匹配,并根据已经匹配的部分字符的信息,跳跃式地移动模式串的指针。

具体来说,BM算法分别构建了坏字符规则和好后缀规则。

坏字符规则用于处理主串中与模式串不匹配的字符,找到最右边的该字符在模式串中的位置,并移动模式串的指针到对齐该字符。

好后缀规则用于处理主串中与模式串匹配的部分,找到最右边的该部分在模式串中的位置,并移动模式串的指针到对齐该部分。

常见经典字符串匹配算法简要介绍

在网络安全的研究中,字符串匹配是一种使用普遍而关键的技术,如杀毒软件、IDS中的特征码匹配、内容过滤等,都需要用到字符串匹配。

作为字符串匹配中的一种特殊情况,近似字符串匹配的研究也同样重要。

这里对经典的字符串匹配算法与思想进行简要分析和总结。

本文的主要参考了《柔性字符串匹配》一书。

不可多得的一部专业书籍,有兴趣者可移步这里下载PDF电子书:柔性字符串匹配下载地址一精确字符串匹配字符串的精确匹配算法中,最著名的有KMP算法和BM算法。

下面分别对几种常用的算法进行描述。

1:KMP算法KMP算法,即Knuth-Morris-Pratt算法,是一种典型的基于前缀的搜索的字符串匹配算法。

Kmp算法的搜索思路应该算是比较简单的:模式和文件进行前缀匹配,一旦发现不匹配的现象,则通过一个精心构造的数组索引模式向前滑动的距离。

这个算法相对于常规的逐个字符匹配的方法的优越之处在于,它可以通过数组索引,减少匹配的次数,从而提高运行效率。

详细算法介绍参考:KMP算法详解(matrix67原创)2:Horspool算法和KMP算法相反,Horspool算法采用的是后缀搜索方法。

Horspool 算法可以说是BM算法的意见简化版本。

在进行后缀匹配的时候,若发现不匹配字符,则需要将模式向右移动。

假设文本中对齐模式最后一个字符的元素是字符C,则Horspool算法根据C的不同情况来确定移动的距离。

实际上,Horspool算法也就是通过最大安全移动距离来减少匹配的次数,从而提高运行效率的。

算法参考:《算法设计与分析基础》第二版清华大学出版社3:BM算法BM算法采用的是后缀搜索(Boyer-Moore算法)。

BM算法预先计算出三个函数值d1、d2、d3,它们分别对应三种不同的情形。

当进行后缀匹配的时候,如果模式最右边的字符和文本中相应的字符比较失败,则算法和Horspool的操作完全一致。

当遇到不匹配的字符并非模式最后字符时,则算法有所不同。

字符串模式匹配bf算法

BF算法,也就是Brute Force算法,是一种基本的字符串模式匹配算法。

它通过遍历文本串,逐一比较字符来实现模式匹配。

以下是BF算法的800字说明:1. 算法原理BF算法的基本原理是在文本串中从左到右依次扫描,对于扫描到的每一个位置,将该位置的文本与模式串中的每个模式字符进行比较,以确定是否存在匹配。

如果找到了匹配,则算法结束;否则,继续扫描下一个位置。

2. 算法步骤(1)初始化两个指针,一个指向文本串的起始位置,另一个指向模式串的起始位置;(2)比较起始位置的字符是否匹配,如果不匹配则算法结束;(3)如果匹配,移动两个指针,分别到下一个位置继续比较;(4)重复步骤(2)和(3),直到文本串完全扫描完或者没有匹配到为止。

3. 算法时间复杂度BF算法的时间复杂度是O(n*m),其中n是文本串的长度,m是模式串的长度。

这是因为每次比较都需要花费一定的时间,而整个过程需要比较n-m+1次。

4. 算法优缺点优点:简单易懂,实现起来相对容易。

缺点:时间复杂度较高,对于较长的文本串和模式串,效率较低。

此外,BF算法只能用于查找单一的模式,对于多个模式的查找需要使用其他算法。

5. 实际应用BF算法在实际应用中主要用于文本搜索、模式匹配等场景。

例如,在搜索引擎中,BF算法常被用于网页的关键词匹配和搜索结果排序。

此外,BF算法还可以用于病毒扫描、文件校验等领域。

总之,BF算法是一种基本的字符串模式匹配算法,适用于简单的文本搜索和模式匹配场景。

虽然其时间复杂度较高,但对于一些特定的应用场景,BF算法仍然是一种有效的方法。

当然,随着计算机技术的发展,还有很多高效的模式匹配算法被提出,如KMP算法、BM算法、Rabin-Karp算法等,可以根据具体应用场景选择合适的算法。

「NOIP2020提高」字符串匹配题解

「NOIP2020提⾼」字符串匹配题解Statement⼩ C 学习完了字符串匹配的相关内容,现在他正在做⼀道习题。

对于⼀个字符串 S,题⽬要求他找到 S 的所有具有下列形式的拆分⽅案数:S=ABC,S=ABABC,S=ABAB…ABC,其中 A,B,C 均是⾮空字符串,且 A 中出现奇数次的字符数量不超过 C 中出现奇数次的字符数量。

并递归地定义 A1=A,A n=A n−1A(n≥2 且为正整数)。

例如 A=abb,则 A3=abbabbabb。

则⼩ C 的习题是求 S=(AB)i C 的⽅案数,其中 F(A)≤F(C),F(S) 表⽰字符串 S 中出现奇数次的字符的数量。

两种⽅案不同当且仅当拆分出的 A、B、C 中有⾄少⼀个字符串不同。

⼩ C 并不会做这道题,只好向你求助,请你帮帮他。

Input本题有多组数据,输⼊⽂件第⼀⾏⼀个正整数 T T 表⽰数据组数。

每组数据仅⼀⾏⼀个字符串 S S,意义见题⽬描述。

S S 仅由英⽂⼩写字母构成。

Output对于每组数据输出⼀⾏⼀个整数表⽰答案。

ExampleInput:3 nnrnnr zzzaab mmlmmloOutput:8 9 16Solve 1⽅法:KMP我们⾸先简要概括题⽬:给定字符串 S,问有多少不同的⾮空字符串 A,B,C 满⾜ S=ABABAB...ABC 且 A 中出现奇数次的字符数不多于 C。

第⼀眼发现:循环节我们知道⼀个 KMP 有⼀个优秀的性质,或者叫做引理:(这⾥ n=|S| )若n,则n−kmp[n] 是最⼩循环节长度若n%(n−kmp[kmp[n]])==0 ,则n−kmp[kmp[n]] 是次⼩循环节长度以此类推(这个不懂的建议看看蓝书或者上⽹)那我们显然有⼀个暴⼒的想法:(字符串下标从 1开始,S[i,j]={s[i],s[i+1]…s[j]})枚举i=3…n−1表⽰C=S[i,n−1]求出S[1,i−1]即 (AB)x的所有循环节对于每⼀个循环节,枚举A具体是什么,根据题⽬条件统计答案注意 A,B,C 皆不能为空串显然,这个是 O(n4)的,⼤致长这个样⼦:for(int i=3;i<=n;++i){vector<int>g;int pos=i-1;while(pos){if((i-1)%(i-1-kmp[pos])==0)g.push_back(kmp[pos]);pos=kmp[pos];}for(int j=0;j<(int)g.size();++j){int len=i-1-g[j];//|AB| = lenfor(int k=1;k<=len;++k){//枚举 A = S[1,k]for(int h=1;h<=k;++h)//统计前 k 个中,出现次数为奇数字符个数,假设为 cntif(cnt<=C 中出现次数为奇数字符数) ans++;}Processing math: 100%}}我们可以⼀层层 for 优化Opt1发现每次判断是否满⾜条件时(A 中出现奇数次的字符数不多于 C)其实是在判断⼀个 f(prefix) ,和⼀个 f(suffix)显然我们可以 O(n) 预处理:void prework(){len=strlen(s);memset(cnt,0,sizeof cnt);for(int i=1,tot=0;i<=len;++i)if((++cnt[s[i]-'a'])&1)pre[i]=++tot;else pre[i]=--tot;memset(cnt,0,sizeof cnt);for(int i=len,tot=0;i;--i)if((++cnt[s[i]-'a'])&1)suf[i]=++tot;else suf[i]=--tot;}这样,最⾥⾯的 for 简化成 O(1):if(pre[k]<=suf[i])ans++;Opt2观察,发现其实对于多个不同的循环节,都有可能枚举同样的 k 进⾏贡献,⽽且,对于⼀个更长的循环节,它应该包含⽐他短的循环节的取值集合。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第八章 字符串匹配
介绍
• 字符串匹配算法是计算机科学中研究得最 为广泛和古老的问题之一。取证领域需要 各种字符串的搜索、排除技术。 • 目前存在各种各样复杂的字符串算法,同 时也存在各种的误解 • 例如:KMP算法在实际中比蛮力方法慢一 倍。BM算法中真正实用的是对原算法高度 简化后的方法
介绍
• 经典的数据结构中对字符串算法介绍得比 较少,但是在安全领域,用得非常广范, 例如IDS,FireWall,Anti Virus等 • 字符串匹配技术本身也在发展例如多模式 匹配、扩展模式匹配、近似模式匹配等等 • 但是由于课程时间限制,我们仅仅介绍概 念上比较简单,又很实用的算法
第一种情况是模式串中无真子串, 如上图的主串 s=“cddcdc”、模式串t=“cdc”的模式匹配过程。当s0=t0, s1=t1,s2≠t2时,算法中取i=1,j=0,使主串下标i值回退, 然后比较s1和t0。但是因t1≠t0,所以一定有s1≠t0,实际上 接下来就可直接比较s2和t0。 可以推广到匹配长度为m-1情况
{
if(str[i] == t.str[j]) // { i++;j++; } else { i = i-j+1;j = 0; } } if(j >= t.size-1) v = i-t.size+1; else v = -1; return v;
}
(3)BF算法的时间复杂度
若n为主串长度,m为子串长度,则串的BF匹配算法最坏的情况下需 要比较字符的总次数为(n-m+1)*m=O(n*m) 最好的情况是:一配就中!主串的前m个字符刚好等于模式串的 m个字符,只比较了m次,时间复杂度为O(m)。 最恶劣情况是:模式串的前m-1个字符序列与主串的相应字符序列比 较总是相等,但模式串的第m个字符和主串的相应字符比较总是不 等,此时模式串的m个字符序列必须和主串的相应字符序列一共比 较n-m+1次,所以总次数为:m*(n-m+1),因此其时间复杂度为 O(n×m)。
当si≠tj(0≤i<n,0≤j<m)时,存在
"si-jsi-j+1…si-1" = "t0t1…tj-1“ 此时若模式串中存在可相互重叠的真子串,满足 "-1" = "tj-ktj-k+1…tj-1" (0<k<j)
则说明模式串中的子串“t0t1…tk-1”已和主串“si-ksik+1…si-1”匹配。下一次可直接比较si和tk;
此时若模式串中不存在可相互重叠的真子串,则说明
在模式串t0t1…tj-1”中不存在任何以t0为首字符的字符串与
“si-jsi-j+1…si-1”中以si-1为末字符的字符串匹配,下一次可 直接比较si和t0。 关于模式串中的真子串问题。我们把模式串中从第一个 字符开始到任一个字符为止的模式串中的真子串定义为next
BF与KMP算法的运行效率比较
回顾BF的最恶劣情况:S与T之间存在大量的部分匹配,比较 总次数为: (n-m+1)*m=O(n*m) 而此时KMP的情况是:由于主串比较位置i无须回退,比较次 数仅为n,即使加上计算next[j]时所用的比较次数m,比较总 次数也仅为n+m=O(n+m),大大快于BF算法。
1.4 可以改进的地方
• 前缀搜索 • 从左到右搜索,如果发现T中已搜索字符串的 后缀是p的前缀,那么就可以移动比1更多的距 离,移动到II的后面
• 后缀搜索
• • 在搜索窗口内从右往左逐个读入正文串中的字符,搜索其与模式串的最长公共后缀。 因为这种搜索方式能跳过正文的一些字符,因而具有亚线性的平均时间复杂度。 基于后缀搜索思想的方法中最著名的就是Boyer-Morre(BM)算法,而其它方法几乎都是 在其基础上的改进,比较有代表性的如Horspool(BMH)、Tuned-BM(TBM)、 Sunday(QS)、SSABS、BR等。BM算法的时间复杂度在最好的情况下为O(n/m),但最 坏的情况下却为O(nm)。尽管理论上BM算法比基于前缀和子串的方法好,但实际应用 中却并不是最快的算法。
k = next[k]; } if(P[k+1]==P[i]) next[i] = k+1; else next[i] = -1; //如果相等而结束, 则找到一对长度为k的前缀字串和后缀字串 //增加了一个相同项 //其他情况
}
}
KMP算法
• • • • • • • • • • • • • • • • • • • • • • int find(char*T, char* pat){ int n = strlen(pat); int *next = new int[n]; calnet(pat, next); char *p=T, *q=pat; int i=0; while(*p!='\0'&&(*(q+i)!='\0')){ if(*p==*(q+i)){ p++; i++; }else{ if(i==0)//pattern的第一个字符就不等,那么搜索窗口后移一个字符 p++; else i = next[i-1]+1; } } if(*(q+i)=='\0') return p-T-n; else return -1; }
1.5 KMP算法
KMP算法是在BruteForce算法的基础上的模式匹配的 改进算法。KMP算法的特点主要是消除了Brute-Force算法的 如下缺点: 主串下标i在若干个字符序列比较相等后,只要 有一个字符比较不相等便需要把下标i的值回退。分两种情况 分析Brute-Force算法的匹配过程:
的,所以问题实际是求搜索窗口“aba”,既是前缀又是后缀的子串
s= a b a c a b a b
t= a b a b
i=3
失败
j=3
总结以上两种情况可以发现,一旦si和tj比较不相等,
主串的si可直接与模式串的tk(0≤k<j)比较,k的确定与 主串s并无关系(因为这个时候k表示Si-j…Si-1的边界,也 就是t0..tj-1的边界),而只与模式串t本身的构成有关, 即从模式串本身就可求出k的值。 一般情况下,设s="s0s1...sn-1",t="t0t1...tm-1",
第一次匹配s=c d d c d c t=c d c 第二次匹配s=c d d c d c t=c d c 第三次匹配s=c d d c d c t=c d c 第四次匹配s=c d d c d c t=c d c
i=2 j=2 i=1 j=0 i=2 j=0 i=5 j=2
失败 失败
失败 成 功
经典字符串匹配相关算法
1.字符串匹配算法
2.多字符串匹配 3.正则表达式匹配 4.近似字符串匹配
第一部分 字符串匹配
1.1位并行和位运算 位并行利用了计算机机器字位运算的内在 并行性,即可以把多个值装入同一个机器 字内,然后只需要一次运算就能更新所有 值。
还可以做算术运算,但是如果一个串跨多个 机器字的时候要注意进位的影响
KMP算法:如何求next
• • • • • • • • • • • void calnext(char* P, int next[]){ next[0] = -1; //第一个元素的next总是-1 for(int i=1; i<strlen(P); i++){
int k = next[i-1]; //因为采用递归的方法, 为了计算next[i], 先记录下next[i-1] while(P[k+1]!=P[i]&&k>=0){ // 递归
KMP算法的思想:
设s为主串,t为模式串,设i为主串s当前比较字符的下标, j为模式串t当前比较字符的下标,令i和j的初值为0。当si = tj时,i和j分别增1再继续比较;否则i不变,j改变为next[j]值 (即模式串右滑)后再继续比较。依次类推,直到出现下列 两种情况之一:一是 j退回到某个j=next[j]值时有si = tj , 则i和j分别增1后再继续比较;二是j退回到j=-1时,令主串和 子串的下标各增1,随后比较si+1和t0 。这样的循环过程一直 进行到变量i大于等于size或变量j大于等于size时为止。
1.3 Brute Force算法
1、 Brute-Force算法
(1)Brute-Force算法的设计思想: 将文本T的第一个字符和模式p的第1个字符比较, 若相等,继续逐个比较后续字符; 若不等,从主串S的下一字符起,重新与T第一个字符比较。 直到主串S的一个连续子串字符序列与模式T相等。返回值为S中 与T匹配的子序列第一个字符的序号,即匹配成功。
如何求next
• 举个例子 假设子串为P:“abacabab”, 且我们将要求的是‘b‟ 的next值, e.g. next[7] 假设next[0~6]均为已知: next[0]=-1, next[1]=-1 , next[2]=0 , next[3]=-1 , next[4]=0 , next[5]=1 ,next[6]=2 (为0-2字符) • "abacabab" • next[6]=2可以说明P[0~2](蓝)与P[4~6](红)是一样 的
[j]函数,则next[j]函数定义为
-1 当j=0时 next[ j ]= max { k | 0<k<j 且‘t0 t1 …tk-1’=‘tj-k tj-k+1…tj-1’ } 0 其他情况 当模式串t中的tj与主串s的si比较不相等时,模式串t中需 重新与主串s的si比较的字符下标为k,即下一次开始比较si和 tk; 若模式串t中不存在如上所说的真子串,有next[j]=0, 则下一次开始比较si和t0;当j=0时令next[j]=-1。
相关文档
最新文档