Experimental data structures of two strings: String Matching (hashed string)

Problem Description

Given two strings and string2 string1, string2 determines whether the sub-strings of string1.

Input

Input data comprises a plurality of sets, each set of test data consists of two rows, the first row represents string1, string2 The second line, and string1 string2 spaces are guaranteed not occur. (String1 and string2 size does not exceed 100 characters)

Output

For each case, if a substring of string1 string2, output "YES", and otherwise outputs "NO".

Sample Input

abc
a
123456
45
abc
ddd

Sample Output

YES
YES
of NO

Single hashing

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

Double hashing

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

 

Guess you like

Origin www.cnblogs.com/Stay-Online/p/11305637.html