求子串-KPM模式匹配-NFA/DFA

求子串

数据结构中对串的5种最小操作子集:串赋值,串比较,求串长,串连接,求子串,其他操作均可在该子集上实现

  • 数据结构中串的模式匹配

KPM模式匹配算法

基本的模式匹配算法

//求字串subString 在串string中的位置function subString(string, subString){
 var i=0,j=0;//当i或j超出范围退出
  while(i<string.length&&j<subString.length){
   if(string[i]==subString[j]){
    ++i;++j
   }
   else{//当匹配不成功时,i由开始位置后移一位
    i=i-j+1;j=0;
   }
 }//如果是j超出范围则返回i-j,如果是i超出范围则表示未找到 if(j>=subString.length) return i-j;
   else return false;
}

看的出来,每当匹配不成功时,i总是回朔本次匹配的开始位置
KPM,一种改进了的模式匹配算法,解决i回朔问题

这里引出了一个很重要的问题‘包含前缀’,

以subString=‘abcabcacab‘,为例。前缀串‘abca‘=‘abc[abca]cab‘方括号中的字串的,如果在该字串之后c处匹配失败,只需要让前缀串的a与括号中的a对其,接着从匹配失败的c处继续匹配。

所以我们需要求出subString在j处匹配失败后,需要向回移动j-k+1的值

假设f(j)代表subString在j之前的包含前缀中最大的k,例如‘abcabca‘中,k-1=1,4,即最大k为5;f(8)=5

那么‘abcabcacab‘中,f(9)=f(8)+(subString[5]?==subString[8]),如果相等,则f(9)=6;如果不相等f(9)需要重新计算,因为subString[9-1]的c导致最大包含前缀不再是abca,而是一个已c结尾的包含前缀字串。实际上没有这样的字串;

blog.csdn.net/yukuninfoaxiom/article/details/6057736

blog.csdn.net/joylnwang/article/details/6778316/

http://www.rudy-yuan.net/archives/182/

www.webhek.com/misc/comparison-sort

  • 编译原理词法分析器

NFA/DFA

时间: 2024-10-03 13:39:00

求子串-KPM模式匹配-NFA/DFA的相关文章

HDU 1686 Oulipo【kmp求子串出现的次数】

The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book: Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, pu

hiho#1445 重复旋律5 求子串数量 后缀自动机

题目传送门 题意:给出一个字符串,求子串的个数. 思路:后缀自动机的题真是每做一题就更理解一些. SAM中的每一状态$p$都代表了一种子串,而p包含的字符串的个数是$len[p]-len[fa[p]]$,所以答案就是$sigma len[i]-len[fa[i]]$,还有答案要开long long. #include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long l

KMP模版 &amp;&amp; KMP求子串在主串出现的次数模版

int next[MAX_LEN]; void creat_next(char *S, int Sn) { int k, q; next[0] = 0; for(k=0, q=1; q<Sn; q++){ while(k>0 && S[k]!=S[q]) k = next[k-1]; if(S[k] == S[q]){ k++; } next[q] = k; } } bool Judge(char *S, char *T, int Sn, int Tn)//S是子串,T是主串

Blue Jeans---poj3080(kmp+暴力求子串)

题目链接:http://poj.org/problem?id=3080 题意就是求n个长度为60的串中求最长公共子序列(长度>=3):如果有多个输出字典序最小的: 我们可以暴力求出第一个串的所有子串,然后判断是否是其他的子串即可: #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int N = 107; char s[N][61]; int Nex

JAVA常见算法题(三十三)---求子串在字符串中出现的次数

计算某字符串中子串出现的次数. public static void main(String[] args) { String s1 = "adcdcjncdfbcdcdcd"; String s2 = "cd"; count(s1, s2); } public static void count(String str1, String str2) { int count = 0; if (str1.equals("") || str2.equa

【动态规划】最大子串和(和前面那个求子串基本一样)

[动态规划]最大子串和 时间限制: 1 Sec  内存限制: 128 MB 题目描述 给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n. 输入 第一行是一个整数N(N<=10)表示测试数据的组数) 每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素.(0<n<=1000000) 输出 对于

触宝 求子串问题

1 #coding = utf-8 2 import sys 3 4 def Sub_string(a,b): 5 c=[0]*len(b) 6 for i in range(len(a)): 7 for j in range(len(b)): 8 if str(a[i]).find(str(b[j]))!=-1: 9 c[j] = c[j] + 1 10 for k in c: 11 print(k) 12 13 if __name__=='__main__': 14 N=int(sys.st

KMP算法模板 求子串和模板串首先匹配的位置

1 #include <cstdio> 2 using namespace std; 3 4 const int MAXN = 1e6 + 10; 5 int nex[MAXN]; 6 int s[MAXN], t[MAXN]; 7 8 void get_nex(int lm) { 9 int i = 0, j = -1; nex[0] = -1; 10 while (i < lm) { 11 if (j == -1 || t[j] == t[i]) { 12 i++; j++; nex

poj 2406 Power Strings求子串在主串中最多叠加次数

#include<stdio.h> #define M 1000010 int n,next[M]; char s[M]; void getNext() { int i=1,j=-1; next[0]=-1; for(;s[i];i++){ while(j!=-1&&s[j+1]!=s[i])j=next[j]; if(s[j+1]==s[i])j++; next[i]=j; } n=i; } int main() { while(scanf("%s",s)