模式匹配KMP
字符串朴素模式匹配算法的2种实现:
//1.朴素的模式匹配算法,用while实现
int StrStr_While(const char* pStr, const char* pSub, int* pos)
{
int nRet = 0;
int pStrLen = strlen(pStr);
int pSubLen = strlen(pSub);
int i = 0, j = 0;
int nLen = pStrLen - pSubLen; if (pStr == NULL || pSub == NULL)
{
nRet = -1;
printf("param input error!");
return nRet;
} while (i < pStrLen && j < pSubLen)
{
if (*(pStr + i) == *(pSub + j))
{
++i;
++j;
}
else
{
i = i - j + 1;
j = 0;
}
} if (j == pSubLen)
*pos = i - j + 1; return nRet;
}
//2.朴素的模式匹配,用for循环实现
int StrStr_For(const char* pStr, const char* pSub, int* pos)
{
int nRet = 0;
int pStrLen = strlen(pStr);
int pSubLen = strlen(pSub);
int i = 0, j = 0;
int nLen = pStrLen - pSubLen; if (pStr == NULL || pSub == NULL)
{
nRet = -1;
printf("param input error!");
return nRet;
} for (i = 0; i <= nLen; ++i)
{
for (j = 0; j < pSubLen; ++j)
{
if (*(pStr + i + j) != *(pSub + j))
break;
} if (j == pSubLen)
{
*pos = i + 1;
break;
}
} return nRet;
}
实现字符串的匹配有高效的算法。那就是KMP算法,实现例如以下:
//取得KMP算法须要用的的next数组
int GetNext(const char* pStr, int nNext[])
{
int nRet = 0;
if (pStr == NULL || nNext == NULL)
{
nRet = -1;
printf("param input error!\n");
return nRet;
} int nLen = strlen(pStr);
int i = 0, j = -1;
nNext[i] = j;
while (i < nLen - 1)
{
if (j == -1 || pStr[i] == pStr[j])
{
++i;
++j;
nNext[i] = j;
}
else
{
j = nNext[j];
}
} return nRet;
} //取next数组的改进型算法!剔除多个反复字符的next数组值持续增长。 int GetNextVal(const char* pStr, int nNext[]) { int nRet = 0; if (pStr == NULL || nNext == NULL) { nRet = -1; printf("param input error!\n"); return nRet; } int nLen = strlen(pStr); int i = 0, j = -1; nNext[i] = j; while (i < nLen - 1) { if (j == -1 || pStr[i] == pStr[j]) { ++i; ++j; if (pStr[i] != pStr[j]) nNext[i] = j; else nNext[i] = nNext[j]; } else { j = nNext[j]; } } return nRet; }
这是针对类似aaaaaaab这种字符串使用上面两个函数取得的next数组值得比較。注意书上的都是字符串从数组的下标为1的位置開始存储的。我改进的算法是还是让字符串从数组下标为0的位置開始存储。
所以上面的next数组值都要相较与原来的值减1。
//调用上面的函数实现KMP高效字符串模式匹配算法!
int Index_KMP(const char* pStr, const char* pSub, int* nPos)
{
int nRet = 0;
if (pStr == NULL || pSub == NULL || nPos == NULL)
{
nRet = -1;
printf("param input error!\n");
return nRet;
} int pStrlen = strlen(pStr);
int pSublen = strlen(pSub); int nNext[255] = { 0 };
//nRet = GetNext(pSub,nNext);
nRet = GetNextVal(pSub, nNext);
if (nRet != 0)
{
printf("call GetNext() func is error!\n");
return nRet;
} int i = 0, j = 0;
while (i < pStrlen && j < pSublen)
{
if (j == -1 || *(pStr + i) == *(pSub + j))
{
++i;
++j;
}
else
{
j = nNext[j];
}
} if (j == pSublen)
*nPos = i - j + 1; return nRet;
}
模式匹配KMP的更多相关文章
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
- 『字符串模式匹配 KMP』
字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...
- 字符串模式匹配——KMP算法
KMP算法匹配字符串 朴素匹配算法 字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...
- 模式匹配KMP算法
关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...
- 模式匹配-KMP算法
/***字符串匹配算法***/ #include<cstring> #include<iostream> using namespace std; #define OK 1 # ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- KMP及其改进算法
本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经 ...
- acm算法模板(1)
1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函数 10 1.6 面积 15 1.7 球面 16 1.8 三角形 17 1.9 三维几 ...
- ACM-ICPC竞赛模板
为了方便打印,不再将代码放到代码编辑器里,祝你好运. ACM-ICPC竞赛模板(1) 1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函 ...
随机推荐
- 基于Visual C++2013拆解世界五百强面试题--题7-链表的各种操作
请用C实现一个链表,实现链表的查找,逆置,替换,删除,添加,清空,创建. 查找.替换和删除.添加里面都会用到遍历链表的操作,所以重点在于遍历, 链表的逆置和清空考虑到效率,我们可以用递归实现, 至于创 ...
- BZOJ 1022
program bzoj1022; var t,n,i,ans,k,j,k1,k2:longint; bo:boolean; begin read(t); to t do begin read(n); ...
- Libev学习笔记4
这一节首先分析Libev的定时器部分,然后分析signal部分. 对定时器的使用主要有两个函数: ev_timer_init (&timeout_watcher, timeout_cb, .) ...
- linux 进程间信号量管理程序之sem_timedwait使用
在开发过程中,有三个独立执行的程序模块,三个模块都对sqlite数据库进行读写操作.sqlite在linux共享性较差,所以须要增加相互排斥信号量解决三个模块訪问数据库该问题. 另外,在增加信号量后, ...
- 用javap命令反编译来分析字符串问题
编写Test.java.编译完后生成Test.class文件,然后对该文件运行javap -c Test命令,生成字节码指令.阅读并得出结论 一.s1和s2指向常量池的不同常量 ①java代码 pub ...
- 获取WebView里的网页文本内容
获取WebView里的网页文本内容,能够採用例如以下方法: public class ComJSInterface { public void loadHtmlContent(String conte ...
- CSS的position(位置)
position: 位置,absolute绝对位置,相对于浏览器边界的位置:relative相对位置,相对于它本应该出现的位置.fixed:固定位置,它不会随着滚动. 设置好position之后,就可 ...
- c#语言基础之组成结构
一.项目结构 .cs--- 源文件(程序代码) .csproj---项目文件(管理文件项) .sln--- 解决方案文件(管理项目) .config---配置文件 函数的四要素:名称.输入. ...
- HTML+CSS基础总结
1. 首先声明正确的文档类型doctype 通常有四种文档类型可供选择: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ...
- JavaSE学习总结第08天_面向对象3
08.01 工具类中使用静态 例: class ArrayTool { //将构造方法私有,外界不能创建该类的对象 private ArrayTool(){} //遍历数组 public stat ...