leetcode 28:Implement strStr()
2015-10-12 20:38
405 查看
题目:
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
思路:
题目大意是让我们找到needle字符串在haystack字符串中第一次出现的位置。这就是字符串的模式匹配问题。
朴素的模式匹配算法是对主串的每一个字符作为子串开头,与要匹配的字符进行匹配。对主串做大循环,每个字符开头做T的长度的小循环,知道匹配成功或全部遍历完成为止。
时间复杂度为O(n*m),显然效率太低。
我们可以用KMP算法来实现,这样可以避免每次检测到不同时回溯到子字符串的开始。具体实现如下:
class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2,0);
NEXT(next, needle);
int i=0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}
void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j]) next[++i] = ++j;
else j = next[j];
}
}
};
算法分析请参考本人的另一篇博文:http://blog.csdn.net/onlyou2030/article/details/49078311
在上述博文中提到了改进的KMP算法,对于较长的连续字符的字符串有较好的提高效率的作用。改动的只是求next函数。
class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2, 0);
NEXT(next, needle);
int i = 0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}
void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j])
if (needle[++i] == needle[++j]) next[i] = next[j]; // 当两个字符相等时要跳过
else next[i] = j;
else j = next[j];
}
}
};
奇怪的是,上面的解法8ms,下面的解法12ms,居然上面快哈。
不过,这与测试字符串有关,若按平均时间来看的话,肯定是下面的更优。
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
思路:
题目大意是让我们找到needle字符串在haystack字符串中第一次出现的位置。这就是字符串的模式匹配问题。
朴素的模式匹配算法是对主串的每一个字符作为子串开头,与要匹配的字符进行匹配。对主串做大循环,每个字符开头做T的长度的小循环,知道匹配成功或全部遍历完成为止。
时间复杂度为O(n*m),显然效率太低。
我们可以用KMP算法来实现,这样可以避免每次检测到不同时回溯到子字符串的开始。具体实现如下:
class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2,0);
NEXT(next, needle);
int i=0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}
void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j]) next[++i] = ++j;
else j = next[j];
}
}
};
算法分析请参考本人的另一篇博文:http://blog.csdn.net/onlyou2030/article/details/49078311
在上述博文中提到了改进的KMP算法,对于较长的连续字符的字符串有较好的提高效率的作用。改动的只是求next函数。
class Solution {
public:
int strStr(string haystack, string needle) {
int size1 = haystack.size(), size2 = needle.size();
if (size2 == 0) return 0;
if (size1 == 0) return -1;
vector<int> next(size2, 0);
NEXT(next, needle);
int i = 0, j = 0;
while (i < size1 && j < size2)
{
if (j == -1 || haystack[i] == needle[j])
{
++i;
++j;
}
else j = next[j];
}
if (j == size2) return i - j;
else return -1;
}
void NEXT(vector<int> &next, string needle)
{
int i=0, j=-1;
next[0] = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j])
if (needle[++i] == needle[++j]) next[i] = next[j]; // 当两个字符相等时要跳过
else next[i] = j;
else j = next[j];
}
}
};
奇怪的是,上面的解法8ms,下面的解法12ms,居然上面快哈。
不过,这与测试字符串有关,若按平均时间来看的话,肯定是下面的更优。
相关文章推荐
- 美团、去哪儿、奇虎360独角兽公司技术薪资分析
- 在ubuntu下,把安装的中文输入法切换出来
- python编码问题初探
- 面试题:异或去重
- 迷宫问题(顺序栈)
- [置顶] UML——九种图 关系
- DB2 里的mongoDB
- 测试工具在测试工作中是什么地位?
- C++对C的扩充(体现在面向过程程序设计部分)
- [mysql] mysql如何实现更新一条记录中某个字段值的一部分呢?
- 动手学习TCP:4种定时器
- 【笔试】57、确定一个字符串的所有字符是否都不同
- MySQL中数据操作DML
- Android中Parcelable接口用法http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
- Unity UIButton切换相应的UI页面动态加载
- 数制转换问题(顺序栈)
- 什么是软件测试,软件测试的目的?
- 【Foundation-26-1】#import <Foundation/NSDictionary.h>字典,旧
- 顺序栈——C++实现
- 蓝懿ios 简易机算计 技术内容和心得