匹配

字符匹配用KMP时间复杂度为O(m+n)

但如果一时间写不出KMP,该怎么办呢,用暴力法吗?

暴力法的时间复杂度为O(mn),不可取

这里介绍一种时间复杂度为O(m)的简单方法

假如str1的长度为m,匹配串的长度为n,其中m>n,则要比较m-n个串,并且每个串比较n次,时间复杂为O(mn)

我们可以用多项式进行匹配,就是把每个子串用多项式转化为一个数字,因为每个ASSIC码都代表一个数字。

如 “abc”
转化为 ‘a’10^2+’b’10+’c’

不能各位简单求和,因为这样就丢失了顺序信息

但这样还是O(mn)的复杂度,因为每个子串的计算的时间复杂度为O(n)

我们可以用滑动的方法把这个复杂度降低

如”abcdea”

用”abc”去匹配

子串1:temp1=’a’10^2+’b’10+’c’
子串2:temp2=(temp1-‘a’10^2)10+’d’
…..

这样子串的计算复杂度为O(1),总的复杂度为O(m)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
using namespace std;


int main()
{

string s1;
string s2;
while (cin>>s1>>s2)
{
int m = s1.length();
int n = s2.length();
if (m < n)
{
printf("-1\n");
continue;
}
int a[1000];
int temp1=0;
for (int i = 0; i < n; i++)
{
temp1 += (s1[i]-'0') * pow(10, n - i - 1);
}
a[0] = temp1;
for (int i = 1; i <= m - n; i++)
{
int first=(s1[i - 1]-'0') * pow(10, n - 1);
int last = (s1[i + n - 1] - '0');
temp1 = (temp1 - first)*10 + last;
a[i] = temp1;
}
int temp2 = 0;
for (int i = 0; i < n; i++)
{
temp2 += (s2[i]-'0') * pow(10, n - i - 1);
}
bool flag = false;
for (int i = 0; i < m-n+1; i++)
{
if (temp2 == a[i])
{
flag = true;
printf("%d\n", i);
}
}
if (flag == false)
printf("-1\n");

}
return 0;
}