字符串哈希刷题(一)

目录

 

前言

题目详情

简单分析

注意事项

完整代码

AC凭证

水话 


前言

学习了之前所发的有关字符串哈希的相关讲解,相信有一部分同学已经按捺不住赶紧上手刷上那么几题了呢!然后本蒟蒻在今天考完机考,马上就拿上了电脑开启了相关的刷题,没想到一个普及组的题目刷了有一个半小时之久,利用昨天一位很厉害的学长说的话:菜是原罪!如果不知道字符串哈希是什么的uu们点击这里:字符串哈希(嘻嘻)!

题目详情

原题是一个英文题目,但是洛谷官网把它翻译了,这是本题的链接:洛谷题目p2957

简单分析

因为已经有了字符串哈希的基础,所以此题,其实只用算出字符串a的前缀和后缀以及字符串b的前缀和后缀的哈希值就可以了,然后进行两次比较,最终得出最长的重复字串个数!

注意事项

不知道看到这的同学们,在思考的时候会不会想,我们这个题目最终可不可以利用二分答案的方法去找到最终的那个最长的答案,我刚开始也是那么想的,结果一个小时都在找此题利用二分的错误在哪。大家可以再自习读读题目,由于题目的特殊性,此题都是在求前缀和后缀,如果用二分的话,那就是一个在找是否存在最长重复子串的问题了,这和我们去计算后缀的哈希值的思想是完全不符合的,最终当然不会得到正确的答案啦!

完整代码

#include<bits/stdc++.h>
using namespace std;
int mod=13331,k=26;  //利用mod防止数字溢出,k表示在26进制下的哈希值 
string a,b;
int sum=0;
long long a1[100];   //记录a字串的哈希值 
long long b1[100];   //记录b字串的哈希值 

//计算前缀的哈希值
long long hash1(string s,int len)  
{
 	long long ans1=0;
	 for(int i=0;i<len;i++)
 	{
 	 	ans1=(ans1*k%mod+(s[i]-'0'))%mod;
	 }
	 return ans1;
}

//计算后缀的哈希值 
long long hash2(string s,int len,int length) 
{
 	long long ans2=0;
	 for(int i=length-len;i<length;i++)
 	{
 	 	ans2=(ans2*k%mod+(s[i]-'0'))%mod;
	 }
	 return ans2;
}

int main()
{
	cin>>a>>b;
	int len1=a.length();
	int len2=b.length();
	//最终答案一定不会超过两字串较小长度的那一个长度 
	int minl=min(len1,len2);
	//sum记录下最终的答案 
    int sum=0;
    //sum1 表示a的前缀与b的后缀最长相等的个数 
    //sum2 表示b的前缀与a的后缀最长相等的个数 
    int sum1=0,sum2=0;  
	//计算a的前缀和b的后缀。
	for(int i=1;i<=minl;i++)
	{
	a1[i]=hash1(a,i);
	b1[i]=hash2(b,i,len2);
	if(a1[i]==b1[i]) sum1=i;
    }
    //计算a的后缀和b的前缀 
    for(int i=1;i<=minl;i++)
	{
	b1[i]=hash1(b,i);
	a1[i]=hash2(a,i,len1);
	if(a1[i]==b1[i]) sum2=i;
    }
    //输出sum1,sum2的最大的那一个 
    sum=max(sum1,sum2);
    cout<<sum<<endl;
}

AC凭证

水话 

本蒟蒻已经分专栏了哦,相信大家会更加清晰的找到对应的块进行阅读,然后呢封面是自己设计的,虽然比较丑,但是嘛我觉得还是很可爱的哈哈哈! 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sheep.ice

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值