字符串朴素模式匹配算法的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的更多相关文章

  1. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  2. 『字符串模式匹配 KMP』

    字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...

  3. 字符串模式匹配——KMP算法

    KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...

  4. 模式匹配KMP算法

    关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...

  5. 模式匹配-KMP算法

    /***字符串匹配算法***/ #include<cstring> #include<iostream> using namespace std; #define OK 1 # ...

  6. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  7. KMP及其改进算法

    本文主要讲述KMP已经KMP的一种改进方法.若发现不正确的地方,欢迎交流指出,谢谢! KMP算法的基本思想: KMP的算法流程: 每当一趟匹配过程中出现字符比较不等时,不需回溯 i 指针,而是利用已经 ...

  8. 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 三维几 ...

  9. ACM-ICPC竞赛模板

    为了方便打印,不再将代码放到代码编辑器里,祝你好运. ACM-ICPC竞赛模板(1) 1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函 ...

随机推荐

  1. 链队列之C++实现

    链队列时建立在单链表的基础之上的.由于是动态分配节点内存,所以无需判满. 链队列的形式如下: 1.队列空 2.队列存在数据 下面介绍下C++实现的链队列,VC6下调试通过. 1.文件组织 2.lq.h ...

  2. [置顶] js操作iframe兼容各种浏览器

    在做项目时,遇到了操作iframe的相关问题.业务很简单,其实就是在操作iframe内部某个窗体时,调用父窗体的一个函数.于是就写了两个很简单的htm页面用来测试,使用网上流行的方法在谷歌浏览器中始终 ...

  3. H面试程序(27):字串转换

    //1 字串转换 //问题描述: //将输入的字符串(字符串仅包含小写字母‘a’到‘z’),按照如下规则,循环转换后输出:a->b,b->c,…,y->z,z->a: //若输 ...

  4. CSDN Markdown简明教程3-表格和公式

    0. 文件夹 文件夹 前言 表格 1 表格 2 表格对齐方式 公式 1 行内公式 2 陈列公式displayed formulas 3 MathJax语法 深入 声明 1. 前言 Markdown是一 ...

  5. Ownership qualifiers of Objective-C: In Details

    虽然这里讲的大部分知识以前都看过,但是时不时出现某些点让我如茅塞顿开: 以前经常会忘记一些细节,这篇文章可以更好的理解细节,巩固知识体系. Ownership qualifiers In Object ...

  6. HTML5 DTD

    HTML5/HTML 4.01/XHTML 元素和有效的 DTD 下面的表格列出了所有的 HTML5/HTML 4.01/XHTML 元素,以及它们会出现在什么文档类型 (DTD) 中: 标签 HTM ...

  7. win7安装 Apache2.2 PHP5.3 MySQL5.6

    . APACHE2.2    经典参考资料 http://blog.csdn.net/yousuosi/article/details/9859507 官方下载地址  http://mirror.bi ...

  8. UnixShell编程(第三版)

    这本书相当老了,04年的,现在  在linux上做实验. 1,date 显示日期. 2,who  显示用户,who am i 3,echo 后面字符串会全部输出,,会过滤掉多余空格,单双引号,分号等. ...

  9. 深入浅出—JAVA(8)

    8.接口与抽象类 不是抽象的类就被称为具体类 不同继承树的类也可以实现相同的接口,类可以实现多个接口.

  10. 看看微软代码的水平——Windows Live Writer 完成开源并推出开源分支

    http://www.oschina.net/news/68860/windows-live-writer-opensource