SCU - 4438 Censor (哈希-字符串)

题目链接

题意:给出一个word字符串和一个page字符串,要求不断重复把p中所有w串删去.

        输出最终结果(eg: w=abc p=aaabcbc  =>   ans=a    )

题解:经典字符串哈希题目.(下面给出模板)

代码如下:

#include  
#include  
#include  
#include  
#include
#include  
using namespace std;
//经典字符串哈希题目
typedef unsigned long long LLU;  //若哈希结果超出LL的范围可以自动取模LL_max
const int maxn = 5e6 + 50;
char w[maxn], p[maxn], ans[maxn];
struct Hash
{
	LLU has = 99991; //以一个相对较大的质数作为哈希值
	LLU has_b[maxn]; //字符串哈希表(用于在母串中p[i]-p[i-len]*has_b[len]时使用,这时得到的才是该子串的哈希值)
	LLU w_has;       //w串的哈希值
	LLU w_len;       //w串的长度
	LLU p_has[maxn];//p串的哈希值
	void init()//初始化
	{
		w_has = 0;     //串哈希值初始化
		p_has[0] = 0;

		has_b[0] = 1;    //哈希表初始化
		for (int i = 1; i <= (int)5e6; i++)
			has_b[i] = has_b[i - 1] * has;
	}
	bool check(int pos) //判断子串是否与母串pos开始len长度串匹配成功
	{
		if (pos >= w_len&&p_has[pos] - p_has[pos - w_len] * has_b[w_len] == w_has)
			return true;
		return false;
	}
	void solve()
	{
		w_len = strlen(w);
		for (int i = 0; i < w_len; i++)    //获得w串的哈希值
			w_has = w_has*has + (w[i] - 'a' + 1);

		int top = 0, p_len = strlen(p);   //top为ans串的长度
		for (int i = 0; i < p_len; i++)   
		{
			ans[top++] = p[i];
			p_has[top] = p_has[top - 1] * has + (p[i] - 'a' + 1);
			if (check(top)) top -= w_len;
		}

		for (int i = 0; i < top; i++)
			printf("%c", ans[i]);
		cout << endl;
	}
}H;
int main()
{
	while (~scanf("%s%s", &w, &p))
	{
		H.init();
		H.solve();
	}
	return 0;
}

 

你可能感兴趣的:(哈希)