数据结构实验之串二:字符串匹配(字符串哈希)

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;
}

 

posted @ 2019-08-05 21:26  Ruby·Z  阅读(258)  评论(0编辑  收藏  举报