字符串匹配的几种算法
字符串匹配算法:找到子串在原字符串中第一次出现的位置
字符串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对准继续向右比较。