字符串匹配算法:找到子串在原字符串中第一次出现的位置
字符串A:abcabcabcabc
字符串B:bca
1、朴素字符串匹配算法
假设有两个指针,一个i指向字符串A的起始位置,一个j指向字符串B的起始位置;
(1)若A[I]==B[j],则i++;j++
(2)在(1)的情况下,若A[i]!=A[j],则j=0,i回到A字符串的上一次的起始位置。
缺点:不适用于那种多个相同的,不能找到第一个相同的位置。
int string_match(char*str1, char*str2)
{
int n = strlen(str1);
int m = strlen(str2);
for (int i=0;i<=n-m;i++)
{
for (int j = 0; j < m; j++)
{
if (str1[i] != str2[j])
break;
if (j == m - 1)
return i - m;
}
}
}
int main()
{
char str1[1000], str2[1000];
cin >> str1 >> str2;
int m = string_match(str1, str2);
cout << m;
return 0;
}
2、简单的模式匹配算法
这是一种有回溯的模式匹配算法,称为Brute-Force算法,简称为BF算法。算法的基本思想为:
设主串为s,模式串为t。
(1)从主串s中下标为0的字符开始,与模式串t中下标为0的字符进行比较。若相同,则继续逐个比较s和t中的后续字符;即i++,j++。
(2)若不同,则从主串s中下标为1的字符开始,与模式串t中下标为0的字符进行比较。
(3)重复(1)(2)过程,直至模式串t全部比较完,则说明匹配成功。否则匹配失败。
int string_match2(char*str1, char*str2)
{
int i=0;
int j=0;
int n = strlen(str1);
int m = strlen(str2);
while (i < n&&j < m)
{
if (str1[i] != str2[j])
{
i = i - j + 1;
j = 0;
}
else
{
i++;
j++;
}
}
if (j >= m)
return i - j;
else
return -1;
}
3、KMP模式匹配算法
该算法取消了主串的回溯,使得算法效率有所提高。
对于主串s和模式串t中,希望某趟在si和tj匹配失败之后,指针i不回溯,模式串t向右滑动到某个位置k上。那滑动到哪个位置k上呢?解决方法为:在si和tj匹配失败之后,指针i不动,模式串t向右滑动,使得tk与si对准继续向右比较。