从C++strStr到字符串匹配算法
字符串的匹配先定义两个名词:模式串和文本串。我们的任务就是在文本串中找到模式串第一次出现的位置,如果找到就返回位置的下标,如果没有找到返回-1.其实这就是C++语言里面的一个函数:
extern char *strstr(char *str1, const char *str2);
对于这个函数的解释:
str1: 被查找目标
str2: 要查找对象
返回值:如果str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
例如:
char str[]="1234xyz";
char *str1=strstr(str,"34");
cout << str1 << endl;
显示的是: 34xyz
返回值是一个指针,这个指针指向文本串中第一次出现模式串的位置。
字符串查找的暴力算法
先看LeetCode上的一道题目,实现这个函数 int strStr(string haystack, string needle); ,要求返回文本串中出现模式串的下标值。
1.如果模式串为NULL,那么直接返回0.
2.如果模式串的长度大于文本串,那么一定查找不到,返回-1.
3.如果存在的话,查找的范围可以限定在文本串的0~s.size()-p.size();
所以暴力算法的代码实现:
int strStr(string haystack, string needle)
{int i = 0;//模式串为空if(needle.empty()){return 0;}//文本串的大小小于模式串if(haystack.size() < needle.size()){return -1;}//确定查找的范围for(i = 0; i <= haystack.size()-needle.size(); ++i){int j = 0;for(j = 0; j < needle.size(); ++j){if(haystack[i+j] != needle[j]){break;}}//forif(j == needle.size()){return i;}}//forif(i == haystack.size()-needle.size() + 1){return -1;}
}
字符串查找的KMP算法
上面的暴力算法,在查找失败以后都要进行回溯,下面再给出一个版本,明显的看到i,j的回溯:
int strStr(string haystack, string needle)
{int sLen = haystack.size();int pLen = needle.size();int i = 0;int j = 0;while(i < sLen && j < pLen){if(haystack[i] == needle[j]){++i;++j;}else{i = i - j + 1;j = 0;}}//whileif(j == pLen){return i - j;}else{return -1;}
}
假设我们已经知道了KMP的next数组,所以每次失配以后,i不回溯,j回溯到next[j]指定的位置。也就是 j = next[j]; 。
int KmpSearch(char *s, char *p)
{int i = 0;int j = 0;int sLen = strlen(s);int pLen = strlen(p);while(i < sLen && j < pLen){//如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++if(j == -1 || s[i] == p[j]){i++;j++;}else{//如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j] //next[j]即为j所对应的next值j = next[j];}}//whileif(j == pLen){return i - j;}else{return -1;}
}
对于上面的j=-1和next[0]=-1作下面的解释:
说完了KMP的大的框架,下面就得说一下next数组的求解过程了:
void GetNext(char *p, int *next)
{int pLen = strlen(p);int j = 0;int k = -1;next[0] = -1;while(j < pLen - 1){//p[k]表示前缀,p[j]表示后缀if(k == -1 || p[j] == p[k]){++k;++j;next[j] = k;//表示在j这个字符之前,能够构成公共前后缀的最大字符数}else{k = next[k];//回溯之前已经有过匹配的前缀}}
}
KMP算法的一个改进
上面的KMP算法已经能够很好的跑出结果来了,但是还可以改进,看下面的一个字符串的匹配:
改进的代码实现:
void GetNextVal(char *p, int *next)
{int pLen = strlen(p);int j = 0;int k = -1;next[0] = -1;while(j < pLen - 1){//p[k]表示前缀,p[j]表示后缀if(k == -1 || p[j] == p[k]){++k;++j;if(p[j] != p[k]){next[j] = k;//表示在j这个字符之前,能够构成公共前后缀的最大字符数}else{next[j] = next[k];//因为不能出现p[j] = p[next[j]],所以当出现时需要继续递归,k = next[k] = next[next[k]]}}else{k = next[k];//回溯之前已经有过匹配的前缀}}
}
再来看一个极端的情况:
转载于:https://www.cnblogs.com/stemon/p/4851524.html
从C++strStr到字符串匹配算法相关推荐
- KMP、BM、Sunday、Horspool、strstr字符串匹配算法的性能比较
KMP.BM.Sunday.Horspool.strstr字符串匹配算法的性能比较 一.简介 简介:字符串匹配算法,顾名思义,在一个给定的字符文本内搜寻出自己想要找的一个字符串,平常所用的各种文本编辑 ...
- 字符串匹配算法(KMP)
文章目录 1. KMP由来 2. KMP算法基本原理 3. 代码 4. Leetcode 28. 实现 strStr() 1. KMP由来 上一节说的BM算法是最高效.最常用的字符串匹配算法. 最知名 ...
- 字符串匹配KMP算法设计C语言,KMP字符串匹配算法笔记
网上有很多解释KMP算法的文章,A_B_C_ABC的这篇很详细,反复看了好几遍,总算理解了个大概,但是总觉得没那么爽快.其实,一种算法各人有各人的理解方法,找到适合自己理解的才容易记住.下面是我对这个 ...
- String Matching 字符串匹配算法——干货从头放到尾
需要的先验知识:动态规划,有限状态机,搜索算法(就是含有state,action和policy)的模型,java.上面这些不需要知道很细,大概懂这些都是啥就可以读懂本文. 写这篇技术博客的动机是因为做 ...
- c++ 字符串匹配算法sunday算法
sunday 算法是一种很高效的字符串匹配算法, 其实现也较kmp算法简单很多 class Sunday {public:const string& needle;int mp[300];Su ...
- 字符串匹配算法之Sunday算法
字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...
- 字符串匹配算法之暴力做法(朴素算法)
字符串匹配算法之暴力做法(朴素算法) 1.字符串匹配算法 1.1 简介 1.2 类型 1.3 示例题目 2.暴力做法(朴素算法) 2.1 暴力算法的思路 2.2 暴力算法的特点: 2.3 暴力算法的J ...
- 数据结构与算法分析(十六)--- 如何设计更高效的字符串匹配算法?(BF + RK + KMP + BMH)
文章目录 一.Brute Force 匹配算法 二.Rabin–Karp 匹配算法 三.Knuth–Morris–Pratt 匹配算法 四.Boyer-Moore-Horspool 匹配算法 五.字符 ...
- 字符串匹配算法(BF算法KMP算法)
字符串匹配算法 暴力匹配(BF)算法 KMP算法 next数组 求next数组的练习 next数组的优化(nextval数组) 练习 暴力匹配(BF)算法 BF算法,即暴力(Brute Force)算 ...
最新文章
- Kubernetes上领先的开源Serverless解决方案有哪些
- 3W法—what,why,how的运用
- 高并发场景下的httpClient优化使用
- Linux的ps aux/ps -ef:风格不同
- webpack打包---报错内存溢出javaScript heap out of memory
- EAI的Spring集成教程
- array函数参数 scala_scala – 在Spark SQL中将数组作为UDF参数传递
- java 防止证书导出_如何把安全证书导入到java中的cacerts证书库
- [python机器学习及实践(2)]Sklearn实现朴素贝叶斯
- python简单文件服务器
- 计算机ppt基础知识题库,计算机二级考试MSOffice考试题库ppt操作题附答案.pdf
- 编写matlab程序设计状态反馈增益阵,利用MATLAB设计状态观测器.pdf
- 执行npm install报错:npm ERR! code EINTEGRITY,npm ERR! 最彻底,最实用的方法就是更新node版本
- 环境微生物学练习题及答案
- 基于SpringBoot的报刊订阅管理系统
- Mac键盘突然失灵怎么办?别急,教你打开辅助键盘
- 【计算机视觉算法岗面经】“吐血”整理:2019秋招资料
- 【Python爬虫】爬取豆瓣电影Top 250
- js使用moment获取当前日期是当前月的第几周
- 浏览器中的data类型的Url格式,data:image/png,data:image/jpeg!
热门文章
- python封装api linux_python Socket编程-python API 与 Linux Socket API之间的关系
- 5 select 选择的值_表单元素之选择类型
- 说一下你对多态的理解?_掌握了多态的特性,写英雄联盟的代码更少啦!
- mysql下载为csv_MySQL 查询结果保存为CSV文件
- 在FFT分析在而立之年的展望与总结
- BL1551模拟开关,封装SC70-6
- 2021年春季学期-信号与系统-第四次作业参考答案-第七小题
- python目标跟踪_商汤开源最大目标跟踪库PySOT,代码已正式上线!
- SHELL脚本 基础一
- 中国计算机专业专科学校排名2015,计算机专科学校排名前十(最出名的10所计算机学院)...