给定目标串 haystack 和模式串 needle ,返回 needle 在 haystack 中第一次出现的位置下标,若 needle 不是 haystack 的子串则返回 -1。

1. Brute-Force Algorithm(暴力算法 / 简单模式匹配)

我自己写了一种双层循环的

 int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int m = haystack.size(), n = needle.size();
for (int i = ; i <= m - n; i++) {
for (int j = ; j < n; j++) {
if (needle[j] != haystack[i + j])
break;
if (j == n - )
return i;
}
}
return -;
}

看了答案发现了一种更高效的方法,虽然时间复杂度同样是 O(m*n),但只要一层循环,非常Nice!

 int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
while (i < m && j < n) {
if (haystack[i] == needle[j]) {
i++;
j++;
} else {
i = i - j + ;
j = ;
}
if (j == n)
return i - j;
}
return -;
}

2.  KMP算法

算法讲解可以参考 http://www.61mon.com/index.php/archives/183/ ,讲解的已经很好了。

KMP的时间复杂度仅为 O(m+n),因为当出现子串与主串某处不匹配时,并不会将遍历主串的下标 i 回溯,而是利用得到的 next 数组将模式子串向右“滑动”尽可能远的一段距离,继续进行比较,提高了效率。

next 数组的求解是关键,它是基于模式子串的最长前后缀,next[i] = needle[0] 到 needle[i - 1] 的字符串的最长相同前后缀的长度。

 void getNext(string needle, vector<int> &next) {
int i = , j = -;
// j 表示最长相同前后缀的长度
next[] = j;
while (i < needle.size()) {
// j == -1 为边界条件判断, j = next[j] 可能使 j 退回到 -1
if (j == - || needle[i] == needle[j]) {
i++;
j++;
next[i] = j;
} else {
j = next[j];
}
}
} int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
vector<int> next(n + );
getNext(needle, next);
while (i < m && j < n) {
if (j == - || haystack[i] == needle[j]) {
i++;
j++;
} else {
j = next[j];
}
if (j == n)
return i - j;
}
return -;
}

改进的KMP算法

 void getNextval(string needle, vector<int> &nextval) {
int i = , j = -;
nextval[] = j;
while (i < needle.size()) {
if (j == - || needle[i] == needle[j]) {
i++;
j++;
// 生成 nextval 数组
if (needle[i] != needle[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
} else {
j = nextval[j];
}
}
} int strStr(string haystack, string needle) {
if (needle.empty()) return ;
int i = , j = ;
int m = haystack.size(), n = needle.size();
vector<int> nextval(n + );
getNextval(needle, nextval);
while (i < m && j < n) {
if (j == - || haystack[i] == needle[j]) {
i++;
j++;
} else {
j = nextval[j];
}
if (j == n)
return i - j;
}
return -;
}

最新文章

  1. [问题]apparmor 问题导致mysql切换datadir目录失败
  2. jsp读取properties文件
  3. 树莓派使用MJPG-Streamer实现网络监控
  4. C#基础总结之四List-Hashtable-冒泡排序
  5. Compute Mean Value of Train and Test Dataset of Caltech-256 dataset in matlab code
  6. [笔记]--Ubuntu安装Sublime Text 2
  7. django-pagination的使用
  8. Ajax交互demo1
  9. expression:stream!=NULL
  10. Linux字符编码转换 UTF8转GB3212
  11. input元素之间的融合
  12. SAXParserFactory
  13. Nginx 安装及配置、负载均衡https网站及转发后页面js、css等路径找不到问题、更换证书导致问题解决
  14. mysql的分表与分区的区别
  15. 算法:时间复杂度+二分查找法(Java/Go/Python)实现
  16. 第25月25日 urlsession
  17. [ Python ] OpenGL
  18. CSS:盒模型和position定位
  19. JAVA 中文 unicode 相互转换 文件读取
  20. scrapy 安装流程和启动

热门文章

  1. CCF计算机网络会议日期
  2. jmeter命令行模式运行,实时获取压测结果
  3. Vue运行报错--not defined
  4. 下载安装tomcat和jdk,配置运行环境,与Intellij idea 2017关联
  5. 6-1 建立客户端与zk服务端的连接
  6. 深入JVM对象引用
  7. synchronized中判断条件用while而不是if
  8. django核心配置项
  9. C# txt文件的读取与写入
  10. 《剑指offer》第四十三题(从1到n整数中1出现的次数)