版本一

求next数组(个人最习惯的写法)

构造next数组其实就是计算模式串s,前缀表的过程。」 主要有如下三步:
1、初始化
2、处理前后缀不相同的情况
3、处理前后缀相同的情况

   void getNext(int* next,const string &s){//初始化//next[i] 表示 i(包括i)之前的子串最长相等的前后缀长度(其实就是j)//所以初始化next[0] = j 。int j=0;next[0]=j;for(int i=1;i<s.size();i++){while(j>0 && s[i]!=s[j]){//处理前后缀不相同的情况j=next[j-1];}if(s[i]==s[j]){//处理前后缀相同的情况j++;}next[i]=j;}
}

代码实现

class Solution {public:void getNext(int* next,const string &s){int j=0;next[0]=j;for(int i=1;i<s.size();i++){while(j>0 && s[i]!=s[j]){j=next[j-1];}if(s[i]==s[j]){j++;}next[i]=j;}
}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[needle.size()];getNext(next, needle);int j = 0; // // 因为next数组里记录的起始位置为-1for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始while(j > 0 && haystack[i] != needle[j]) { // 不匹配j = next[j-1]; // j 寻找之前匹配的位置}if (haystack[i] == needle[j ]) { // 匹配,j和i同时向后移动 j++; }if (j == (needle.size() ) ) { // 文本串s里出现了模式串treturn (i - needle.size() + 1); }}return -1;}
};

版本二

求next数组(-1操作)

如果我们这样写

void getNext(int* next, const string& s){int j = 0;next[0] = j;for(int i = 1; i < s.size(); i++) { // 注意i从1开始while (j >= 0 && s[i] != s[j]) { // 前后缀不相同了j = next[j]; // 向前回溯}if (s[i] == s[j]) { // 找到相同的前后缀j++;}next[i] = j; // 将j(前缀的长度)赋给next[i]}
}

那么构造前缀表的时候会陷入死循环,而不是文本串 与 模式串匹配的时候陷入死循环。


此时i与j并不相同,那么j需要回退,此时j = 1,而next[1]=1,j = next[j]陷入死循环。

初始化

定义两个指针i和j,j指向前缀末尾位置(严格来说是末尾位置减一的位置),i指向后缀末尾位置。
然后还要对next数组进行初始化赋值,如下:

int j = -1;
next[0] = j;

j 为什么要初始化为 -1呢,是因为之前说过 前缀表要统一进行减一的操作

next[i] 表示 i(包括i)之前的子串最长相等的前后缀长度(其实就是j)所以初始化next[0] = j 。

处理前后缀不相同的情况

因为j初始化为-1,所以遍历模式串s的循环下表i 要从 1开始,进行s[i] 与 s[j+1]的比较。

for(int i = 1; i < s.size(); i++) {

如果 s[i] 与 s[j+1]不相同,也就是遇到 前后缀末尾不相同的情况,就要向前回溯。

怎么回溯呢?

next[j]就是记录着j(包括j)之前的子串的相同前后缀的长度。

那么 s[i] 与 s[j+1] 不相同,就要找 j+1前一个元素在next数组里的值(就是next[j])。

while (j >= 0 && s[i] != s[j + 1]) { // 前后缀不相同了j = next[j]; // 向前回溯
}

处理前后缀相同的情况

如果s[i] 与 s[j + 1] 相同,那么就同时向后移动i 和j 说明找到了相同的前后缀,同时还要将j(前缀的长度)赋给next[i], 因为next[i]要记录相同前后缀的长度。

if (s[i] == s[j + 1]) { // 找到相同的前后缀j++;
}
next[i] = j;

Next数组代码实现

   void getNext(int* next,string &s){int j=-1;next[0]=j;for(int i=1;i<s.size();i++){// 注意i从1开始//j>=0是因为j初始值为-1,当ab,j+1指向a的时候,不加j>=0这个条件,j会回退到当前位置的前一个位置所对应的next数组的值,即j=next[j+1-1](j=next[-1])的位置造成内存越界。while(j>=0 && s[i]!=s[j+1]){// 前后缀不相同了j=next[j];// 向前回溯}if(s[i]==s[j+1]){// 找到相同的前后缀j++;}next[i]=j;//将j(前缀的长度)赋给next[i]}
}

整体代码实现

class Solution {public://根据模式串求next数组void getNext(int* next,string &s){int j=-1;next[0]=j;for(int i=1;i<s.size();i++){//j>=0是因为j初始值为-1,当ab,j+1指向a的时候,不加j>=0这个条件,j会回退到当前位置的前一个位置所对应的next数组的值,即j=next[j+1-1](j=next[-1])的位置造成内存越界。while(j>=0 && s[i]!=s[j+1]){j=next[j];}if(s[i]==s[j+1]){j++;}next[i]=j;}
}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}int next[needle.size()];getNext(next, needle);int j = 0; // // 因为next数组里记录的起始位置为-1for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始while(j > 0 && haystack[i] != needle[j]) { // 不匹配j = next[j-1]+1; // j 寻找之前匹配的位置}if (haystack[i] == needle[j]) { // 匹配,j和i同时向后移动 j++; }if (j == (needle.size() ) ) { // 文本串s里出现了模式串treturn (i - needle.size() + 1); }}return -1;}
};

个人建议使用版本一 易理解

实现strstr(****)相关推荐

  1. LeetCode简单题之实现 strStr()

    题目 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始).如果不存在 ...

  2. strchr strstr函数php,PHP字符串函数之 strstr stristr strchr strrchr

    strstr -- 查找字符串的首次出现,返回字符串从第一次出现的位置开始到该字符串的结尾或开始. stristr -- strstr 函数的忽略大小写版本 strchr -- strstr 函数的别 ...

  3. strstr函数头文件_C语言(函数)学习之strstr strcasestr

    一.strstr函数使用 [1] 函数原型 char *strstr(const char *haystack, const char *needle); [2] 头文件 #include [3] 函 ...

  4. 【力扣网练习题】实现 strStr()

    实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...

  5. 模拟实现: strstr strcpy strlen strcat strcmp memcpy memmove

    模拟实现: strstr strcpy strlen strcat strcmp memcpy memmove ================================ 1 strstr 字符 ...

  6. 【每日一算法】实现strStr()

    微信改版,加星标不迷路! 每日一算法-实现strStr() 作者:阿广 阅读目录 ? 题目 ? 解析 ? 完整代码 1 题目 实现 strStr() 函数. 给定一个 haystack 字符串和一个 ...

  7. 实现 strStr()

    实现 strStr() 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始).如果不存在,则返回  - ...

  8. strstr php文档,php字符串函数学习之strstr()

    /* 定义和用法 strstr() 函数搜索一个字符串在另一个字符串中的第一次出现. 该函数返回字符串的其余部分(从匹配点).如果未找到所搜索的字符串,则返回 false. 语法 string str ...

  9. 【C语言】 strstr查找子字符串函数以及模拟实现讲解

    strstr 字符串查找函数 返回的是相同子串的第一个出现的的地址   返回类型是 char* 返回的是相同子串的第一个出现的的地址   参数是 const char* str1 ,const cha ...

  10. 从C++strStr到字符串匹配算法

    字符串的匹配先定义两个名词:模式串和文本串.我们的任务就是在文本串中找到模式串第一次出现的位置,如果找到就返回位置的下标,如果没有找到返回-1.其实这就是C++语言里面的一个函数: extern ch ...

最新文章

  1. Linux RAR 安装和使用详细说明
  2. linux 文件拷贝io,NIO拷贝文件真的比IO拷贝文件效率高?
  3. C# .NET Web API 如何自訂 ModelBinder
  4. JavaScript代码检查工具——JSLintMate
  5. 骨牌覆盖(51Nod-1031)
  6. 网站加载速度 优化_您肯定要优化网站的加载速度。 这是如何做。
  7. Java 代码性能优化总结
  8. STM32零碎问题记录
  9. 银河麒麟系统怎么安装微软雅黑字体
  10. 听哥一句劝,CSDN史上最强插件你把握不住(文末可抽取机械键盘,CSDN年卡会员)
  11. MSN Messenger的用户管理
  12. angular使用高德地图
  13. Android 移动网络接入点名称(APN)
  14. eclipse和myeclipse的he user operation is wating问题
  15. Uniapp——使用安卓原生插件
  16. 渗透测试-越权漏洞之垂直越权和水平越权
  17. 软嵌171 王学晨 作业二 时事评论
  18. 关于Flutter的渠道(channels):master、dev和beta
  19. CCNA中文笔记第11章Wide Area Networking Protocols
  20. 宏杉科技IPO终止审查,资本需对中国存储更多包容!

热门文章

  1. objective-c高级编程 笔记
  2. 20169214 2016-2017-2 《网络攻防实践》实验二学习总结
  3. 【Weiss】【第03章】练习3.20:中缀表达式转后缀表达式
  4. 精通CSS+DIV网页样式与布局——CSS文字效果
  5. 关于MultipleOutputFormat若干小记
  6. 【数据结构与算法】之深入解析“奇偶链表”的求解思路与算法示例
  7. iOS之深入解析内存管理散列表SideTables和弱引用表weak_table的底层原理
  8. iOS之深入定制基于PLeakSniffer和MLeaksFinder的内存泄漏检测工具
  9. 2015年第六届蓝桥杯C/C++ A组国赛 —— 第五题:切开字符串
  10. Netty实战 IM即时通讯系统(七)数据传输载体ByteBuf介绍