一、朴素模式匹配
思路:
在主串s1中找字串s2,找到返回s1中的下标,找不到返回-1,可以指定寻找开始下标pos,pos的默认值为0。
int stringIndex(std::string s1, std::string s2, int pos = 0)
{
long long n1 = s1.size(), n2 = s2.size();
for(long long i = pos; i <= n1 - n2; ++i)
{
long long j = 0;
while(j < s2.size() && s1[i + j] == s2[j])
{
++j;
}
if(j == s2.size())
return i;
}
return -1;
}
二、KMP模式匹配
KMP算法,算法思路网上很多,不赘述。参数含义同上
int stringIndexKMP(std::string s1, std::string s2, long long pos = 0)
{
long long n1 = s1.size(), n2 = s2.size();
std::vector<long long> next(n2, 0);
for(long long i = 1, k = 0; i < n2; ++i)
{
while(k != 0 && s2[i] != s2[k])
{
k = next[k-1];
}
if(s2[i] == s2[k])
{
++k;
}
next[i] = k;
}
for(long long i = pos, j = 0; i < n1;)
{
while(i < n1 && j < n2 && s1[i] == s2[j])
{
++j;
++i;
}
if(j == n2)
{
return i - j;
}
else if(j == 0)
{
++i;
}
else
{
j = next[j - 1];
}
}
return -1;
}
完整代码
#ifndef ZSZ_ALGORITHM
#define ZSZ_ALGORITHM
#include "string"
#include "vector"
int stringIndex(std::string s1, std::string s2, int pos = 0)
{
long long n1 = s1.size(), n2 = s2.size();
for(long long i = pos; i <= n1 - n2; ++i)
{
long long j = 0;
while(j < s2.size() && s1[i + j] == s2[j])
{
++j;
}
if(j == s2.size())
return i;
}
return -1;
}
int stringIndexKMP(std::string s1, std::string s2, long long pos = 0)
{
long long n1 = s1.size(), n2 = s2.size();
std::vector<long long> next(n2, 0);
for(long long i = 1, k = 0; i < n2; ++i)
{
while(k != 0 && s2[i] != s2[k])
{
k = next[k-1];
}
if(s2[i] == s2[k])
{
++k;
}
next[i] = k;
}
for(long long i = pos, j = 0; i < n1;)
{
while(i < n1 && j < n2 && s1[i] == s2[j])
{
++j;
++i;
}
if(j == n2)
{
return i - j;
}
else if(j == 0)
{
++i;
}
else
{
j = next[j - 1];
}
}
return -1;
}
#endif