经典算法整理之字符串匹配
2016-03-22 14:13
423 查看
一、题目描述
长为n的字符串中匹配长度为m的子串
二、 算法分析
1、简单匹配:将主串S中某个位置i起始的子串和模式串T相比较。即从 j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较(
j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 i 增1,而 j 退回至0,重新开始新一轮的匹配。
2、KMP算法
1)、求串的模式值
(1)next[0]=
-1 意义:任何串的第一个字符的模式值规定为-1。
(2)next[j]=
-1 意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
(3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个字符与开头的k个字符相等,且T[j]
!= T[k](1≤k<j)。即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]且T[j]
!= T[k].(1≤k<j);
[align=left](4) next[j]=0 意义:除(1)(2)(3)的其他情况。[/align]
[align=left]
[/align]
2)
o(m)+o(n)
长为n的字符串中匹配长度为m的子串
二、 算法分析
1、简单匹配:将主串S中某个位置i起始的子串和模式串T相比较。即从 j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较(
j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 i 增1,而 j 退回至0,重新开始新一轮的匹配。
2、KMP算法
1)、求串的模式值
(1)next[0]=
-1 意义:任何串的第一个字符的模式值规定为-1。
(2)next[j]=
-1 意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
(3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个字符与开头的k个字符相等,且T[j]
!= T[k](1≤k<j)。即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]且T[j]
!= T[k].(1≤k<j);
[align=left](4) next[j]=0 意义:除(1)(2)(3)的其他情况。[/align]
[align=left]
[/align]
void get_nextval(const cha<pre name="code" class="cpp">void get_nextval(const char *Tvoid getInterval( const char*T,int next[]) { // 求模式串T的next函数值并存入数组 next。 int j = 0, k = -1; next[0] = -1; while ( T[j] != '/0' ) { if (k == -1 || T[j] == T[k]) { ++j; ++k; if (T[j]!=T[k]) next[j] = k; else next[j] = next[k]; } else k = next[k]; } }
2)
int KMP(const char *Text,con int KMP(const char*Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。 { if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )// return -1;//空指针或空串,返回-1。 int len=0; const char *c=Pattern; while(*c++!='\0')//移动指针比移动下标快。 ++len;//字符串长度。 int *next=new int[len+1]; get_nextval(Pattern,next);//求Pattern的next函数值 int index=0,i=0,j=0; while(Text[i]!='\0' && Pattern[j]!='\0' ){ if(Text[i]== Pattern[j]){ ++i;// 继续比较后继字符 ++j; } else{ index += j-next[j]; if(next[j]!=-1) j=next[j];// 模式串向右移动 else{ j=0; ++i; } } }//while delete []next; if(Pattern[j]=='\0') return index;// 匹配成功,返回匹配首字符下标 else return -1; }3、复杂度
o(m)+o(n)
int
相关文章推荐
- 1.4-Memcached基本操作
- java中volatile关键字的含义
- iOS知识树,知识点
- 如何在Ubuntu手机上让自己的应用退到后台还继续运行
- 调试lua代码
- hot spot 热点 setHotSpot()
- 洛谷P1415 拆分数列
- 判断当前viewcontroller是push还是present的方式显示的
- 大型网站架构不得不考虑的 10 个问题
- spring MVC 时间转date(四)--mybatis传入起始时间时,但这传入时间的参数不是bean里的解法
- SYNONYMS
- 程序心谈
- HDU 3605(多重最大匹配)
- 每天一个linux命令(1):ls命令
- 关于this指针
- Xcode编译: pngcrush caught libpng error解决方法
- RCP的插件开发的简单知识
- latex使用相关
- 第四周项目16-递归求Fibnacci数
- 中国菜刀Cknife(C刀)自定义模式秒过安全狗. php过狗一句话,asp过狗一句话.