Problem Description
给定两个字符串string1和string2,判断string2是否为string1的子串。
Input
输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2,string1和string2中保证不出现空格。(string1和string2大小不超过100字符)
Output
对于每组输入数据,若string2是string1的子串,则输出"YES",否则输出"NO"。
Sample Input
abc
a
123456
45
abc
ddd
Sample Output
YES
YES
NO
#include <bits/stdc++.h>
#define ll long long
typedef unsigned long long ull;
using namespace std;
const ull base = 131;
ull mul[1000010];
ull Hash[1000010];
int main() {
ios::sync_with_stdio(false);
mul[0] = 1;
for(int i = 1; i < 110; i++) mul[i] = mul[i-1] * base;
string str1, str2;
while(cin >> str1 >> str2) {
int len1 = str1.size();
int len2 = str2.size();
for(int i = 0; i < len1; i++) {
Hash[i+1] = Hash[i]*base + str1[i];
}
ull sum = 0;
for(int i = 0; i < len2; i++) {
sum = sum * base + str2[i];
}
int flag = 0;
int l = 1, r = len2;
while(r <= len1) {
ull t = Hash[r] - Hash[l-1]*mul[len2];
if(t == sum) flag = 1;
l++, r++;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
双哈希方法
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll base = 131;
const ll mod1 = 1e9+7;
const ll mod2 = 1e9+9;
struct node {
ll a, b;
}Hash[1000010];
ll mul1[1000010];
ll mul2[1000010];
int main() {
string str1, str2;
mul1[0] = 1;
mul2[0] = 1;
for(int i = 1; i < 1000010; i++) {
mul1[i] = mul1[i-1]*base % mod1;
mul2[i] = mul2[i-1]*base % mod2;
}
while(cin >> str1 >> str2) {
ll sum1 = 0, sum2 = 0;
int len1 = str1.size();
int len2 = str2.size();
for(int i = 0; i < len1; i++) {
Hash[i+1].a = (Hash[i].a * base + str1[i] % mod1);
Hash[i+1].b = (Hash[i].b * base + str1[i] % mod2);
}
for(int i = 0; i < len2; i++) {
sum1 = (sum1 * base + str2[i]) % mod1;
sum2 = (sum2 * base + str2[i]) % mod2;
}
int l = 1, r = len2;
int flag = 0;
while(r <= len1) {
if(sum1 == (((Hash[r].a - Hash[l-1].a*mul1[len2]%mod1) % mod1 + mod1) % mod1) &&
sum2 == (((Hash[r].b - Hash[l-1].b*mul2[len2]%mod2) % mod2 + mod2) % mod2))
flag = 1;
l++, r++;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}