字符串hash(scu4438)

Censor

frog is now a editor to censor so-called sensitive words (敏感词).

She has a long text pp. Her job is relatively simple -- just to find the first occurence of sensitive word ww and remove it.

frog repeats over and over again. Help her do the tedious work.

Input

The input consists of multiple tests. For each test:

The first line contains 11 string ww. The second line contains 11 string pp.

(1≤length of w,p≤5⋅1061≤length of w,p≤5⋅106, w,pw,p consists of only lowercase letter)

Output

For each test, write 11 string which denotes the censored text.

Sample Input

    abc
    aaabcbc
    b
    bbb
    abc
    ab

Sample Output

    a
    
    ab

字符串hash可以解决这道题在这里推荐一个博客可以很好的了解字符串hash的集中模式和其安全系数。在这里直接上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
using namespace std;
typedef long long ll;
const int maxn = 5e6 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll Hash = 1e7 + 9;
const ll mode = 1e9 + 7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}
char strA[maxn],strB[maxn];
char tmp[maxn];
ll hb[maxn];
ll preHash[maxn];
void presolve(){
	preHash[0] = 1;
	for(int i = 1; i < maxn; i++){
		preHash[i] = preHash[i - 1] * Hash % mode; 
	}
}
int main(){
	//ios::sync_with_stdio(false);
	presolve();
	while(~scanf("%s%s",strA,strB)){
		int lena = strlen(strA);
		int lenb = strlen(strB);
		ll ha = 0, top = 0;
		if(lena > lenb){
			printf("%s\n",strB);
			continue;
		}
		hb[0] = 0;
		for(int i = 0; i < lena; i++)ha = ((ha*Hash%mode) + strA[i]-'a'+1)%mode;
		for(int i =0; i < lenb; i++){
			tmp[top++] = strB[i];
			hb[top] = ((hb[top-1]*Hash%mode) + strB[i]-'a'+1) % mode;
			if(top >= lena && (((hb[top] - hb[top-lena]*preHash[lena])%mode + mode)%mode==ha)){
				top -= lena;
			}
		}
		for(int i = 0; i < top; i++){
			cout << tmp[i];
		}cout << endl;
	}
	return 0;
}

使用ull来做的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
using namespace std;
typedef long long ll;
const int maxn = 5e6 + 10;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll mod = 1e9 + 7;
inline int read(){
    int ret=0,f=0;char ch=getchar();
    while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
    while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
    return f?-ret:ret;
}

char str[maxn],s[maxn]; 
const ll Hash = 1e5 +7;
int n,m;
ll multi[maxn];
ll Stack[maxn], Hash_str;
char ans[maxn];

inline bool check(int pos){
	if(pos >= n){
		if(Stack[pos] - Stack[pos - n] * multi[n] == Hash_str)
			return true;
	}
	return false;
}

void init(){
	multi[0] = 1;
	for(int i = 1; i < maxn; i++){
		multi[i] = multi[i-1] * Hash;
	}
}

int main(){
	init();
	while(~scanf("%s%s",str,s)){
		n = strlen(str);
		m = strlen(s);
		Hash_str = 0;
		for(int i = 0; i < n; i++){
			Hash_str = Hash_str * Hash + *(str + i);
		}
		Stack[0] = 0;
		int top = 0;
		for(int i = 0; i < m; i ++){
			ans[top++] = s[i];
			Stack[top] = Stack[top - 1] * Hash + *(s + i);
			if(check(top)) top -= n;
		}
		for(int i = 0; i < top; i++)
			printf("%c",ans[i]);
		puts("");
	}
	
	return 0;
}

继续努力加油:

猜你喜欢

转载自blog.csdn.net/ab1605014317/article/details/83929788