字符串查找(又称查找子字符串),是字符串操作中一个很有用的函数。你的任务是实现这个函数。
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。
如果不存在,则返回 -1。
样例
如果 source = “source” 和 target = “target”,返回 -1。
如果 source = “abcdabcdefg” 和 target = “bcd”,返回 1。
对于这个问题可以使用暴力算法求解也可以使用kmp算法
1. 暴力算法
class Solution {
public:
/**
* Returns a index to the first occurrence of target in source,
* or -1 if target is not part of source.
* @param source string to be scanned.
* @param target string containing the sequence of characters to match.
*/
int strStr(const char *source, const char *target) {
// write your code here
if (!source || !target)
return -1;
int slen = strLength(source);
int tlen = strLength(target);
for (int i = 0; i <= slen - tlen; ++i) {
int j = 0;
while (j < tlen) {
if (source[i+j] == '\0' || source[i+j] != target[j])
break;
++j;
}
if (j == tlen)
return i;
}
return -1;
}
private:
int strLength(const char *str) {
int len = 0;
while (str[len])
++len;
return len;
}
};
2.KMP算法
对于KMP算法不熟悉的可以看这blog
class Solution {
public:
/**
* Returns a index to the first occurrence of target in source,
* or -1 if target is not part of source.
* @param source string to be scanned.
* @param target string containing the sequence of characters to match.
*/
int strStr(const char *source, const char *target) {
if(!source || !target)
return -1;
int slen = strLength(source);
int tlen = strLength(target);
int q = 0;
if (source[0] =='\0' && target[0]=='\0')
return 0;
if(target[0] == '\0')
return 0;
auto prefix = computePrefix(target);
for(int i = 0; i < slen; ++i) {
while (q > 0 && target[q] != source[i])
q = prefix[q];
if(target[q] == source[i])
++q;
if (q == tlen)
return i-tlen+1;
}
return -1;
}
private:
int strLength(const char *str) {
int len = 0;
while (str[len])
++len;
return len;
}
vector<int> computePrefix(const string P){
int m = P.size();
vector<int> prefixTable(m, 0);
int k = 0;
for(int q = 1; q < m; ++q) {
while(k > 0 && P[k] != P[q])
k = prefixTable[k];
if(P[k] == P[q])
++k;
prefixTable[q] = k;
}
return prefixTable;
}
};