当前位置:网站首页>String hash, find the string hash value after deleting any character, double hash
String hash, find the string hash value after deleting any character, double hash
2022-07-04 01:04:00 【Selvaggia】
String hash , Find the string hash value after deleting any character , Double hash
- subject
- ** Ideas :**
- Find the string hash value after deleting any character
- How to calculate the hash value after changing the original string by several letters .( But there is one limitation , When hashing a string , There's only one variable , Instead of opening an array to record the hash value of each bit )
- Double hash
- Double hash template
subject
https://ac.nowcoder.com/acm/contest/1076/G
Title Description
Here are two strings of lowercase letters S,T, Guarantee S The length of alpha is greater than or equal to alpha T, Now you have to delete T One character in the string , bring T String into S The substring of a string , Output the deleted location , If there are multiple legal positions , The one with the smallest output , If there is no legal location , Output -1
Input description :
The first line of input string S ( 2 < = ∣ S ∣ < = 3 e 5 ) S(2 <= |S| <= 3e^5) S(2<=∣S∣<=3e5)
The second line of input string T ( 2 < = ∣ T ∣ < = S ) T(2 <= |T| <= S) T(2<=∣T∣<=S)
Output description :
Output a number
Example 1
Input
aaaab
aabaa
Output
3
Example 2
Input
aaaa
aaa
Output
1
Example 3
Input
abcd
xyz
Output
-1
Ideas :
Simple hash , hold s The continuous length in the string is len_t-1 The substring of is converted to the corresponding value , Deposit in map in ; And then t Take each character out of the string , Convert a substring with one character removed into a numeric value , if map If there is such a value in, the legal answer is found .
#include<iostream>
#include<map>
#include <string.h>
using namespace std;
const int N=3e5+10,P=131;
typedef unsigned long long ULL;
char s[N];
char t[N];
ULL hs[N];
ULL ht[N];
//int p[N]; Just test a set of data , Fast exponentiation is good , Not all pretreatment , It takes too much time
ULL quickpow(ULL b,ULL e){
// The data type of the parameter must always be the same as the return value ,int There must be a mistake , About the data characteristics of fast power ?
ULL res=1;
while(e){
if(e&1)res*=b;
b*=b;
e>>=1;
}
return res;
}
ULL getHs(int l,int r){
if(l>r)return 0;
return hs[r]-hs[l-1]*quickpow(P,r-l+1);
}
ULL getHt(int l,int r){
if(l>r)return 0;
return ht[r]-ht[l-1]*quickpow(P,r-l+1);
}
map<ULL,int> mp;
int main(){
cin>>s+1>>t+1;
int ls=strlen(s+1);
int lt=strlen(t+1);
// p[0]=1;
for(int i=1;i<=ls;i++){
// p[i]=p[i-1]*P;
hs[i]=hs[i-1]*P+s[i];
}
for(int i=1;i<=lt;i++){
ht[i]=ht[i-1]*P+t[i];
}
for(int i=1;i<=ls-lt+1;i++){
// Only according to s The length of the prefix hash value of is lt-1 The hash of the substring of is ok ls-(lt-1)
mp[getHs(i,i+lt-2)]=1;//i+(lt-1)-1
}
// for(int i=lt-1;i<=ls;i++){
// ULL k=hs[i]-hs[i-lt+1]*quickpow(P,lt-1);
// mp[k]=1;
// }
// enumeration t Delete in t[i] Hash value of ,ht[1->i-1]+ht[i+1,lt]
for(int i=1;i<=lt;i++){
ULL k=ht[i-1]*quickpow(P,lt-i)+getHt(i+1,lt);
//!!! The hash value of the string after the splicing of two strings is not directly added , First fill the previous string 0
if(mp[k]==1){
cout<<i;
return 0;
}
}
cout<<"-1";
return 0;
}
Find the string hash value after deleting any character
ULL k=ht[i-1]*quickpow(P,lt-i)+getHt(i+1,lt);
How to calculate the hash value after changing the original string by several letters .( But there is one limitation , When hashing a string , There's only one variable , Instead of opening an array to record the hash value of each bit )
If you push the formula, don't push , Just record the formula results :
First, specify the subscript of the string from 1 Start , The string length is len, The elements that change are s[i], take s[i] To be changed to c
h = h + ( c − s [ i ] ) ∗ p ( l e n − i ) ; h=h+(c−s[i])∗p^{(len−i)}; h=h+(c−s[i])∗p(len−i);
Double hash
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
char s[maxn],t[maxn];
long long base[3]={
0,23,29},mod[3]={
0,100000000+7,100000000+9},h[3][maxn],f[3][maxn];
map<long long,int >mp_1,mp_2;
long long ksm(long long res,long long cnt,long long mo)
{
long long sum=1;
while(cnt>0)
{
if(cnt&1)sum=(sum*res)%mo;
res=(res*res)%mo;
cnt>>=1;
}
return sum;
}
int main()
{
//memset(h,0,sizeof(h));
//memset(f,0,sizeof(f));
scanf("%s%s",s+1,t+1);
int len_s=strlen(s+1);
int len_t=strlen(t+1);
for(int i=1;i<=len_s;i++)
{
for(int k=1;k<=2;k++)
h[k][i]=(h[k][i-1]*base[k]+s[i]-'a'+1)%mod[k];
}
long long res[3];
for(int i=len_t-1;i<=len_s;i++)
{
for(int k=1;k<=2;k++)
res[k]=(h[k][i]-h[k][i-len_t+1]*ksm(base[k],len_t-1,mod[k])%mod[k]+mod[k])%mod[k];
mp_1[res[1]]=1;
mp_2[res[2]]=1;
}
for(int i=1;i<=len_t;i++)
{
for(int k=1;k<=2;k++)
f[k][i]=(f[k][i-1]*base[k]+t[i]-'a'+1)%mod[k];
}
for(int i=1;i<=len_t;i++)
{
for(int k=1;k<=2;k++)
res[k]=(f[k][len_t]-f[k][i]*ksm(base[k],len_t-i,mod[k])%mod[k]
+f[k][i-1]*ksm(base[k],len_t-i,mod[k])%mod[k]+mod[k])%mod[k];
if(mp_1[res[1]]==1&&mp_2[res[2]]==1)
{
cout<<i;
return 0;
}
}
cout<<-1<<endl;
}
Double hash template
Double hash is a conflict resolution scheme in open address hash , That is to say, if one hash cannot solve the problem , To hash again , Different from the rehash method , The hash function used for the second time is different from that used for the first time :
https://www.cnblogs.com/energy1010/p/5802942.html
#include <iostream>
usinh namepace std;
typedef long long ll;
const int N=1e6+10;
const int mod1=1e9+7;// If there is any error, modify it manually
const int mod2=1e9+9;
ll has1[N],has2[N];
ll bas1[N],bas2[N];// If you use quickpow Don't use this , It mainly depends on the data range , Decide whether to preprocess or fast power
const int p1=131,p2=13331;
// has1[0]=has2[0]=0;// Hash value cannot be 0, Subscript from 1 Start
bas1[0]=bas2[0]=1;
int len=strlen(s+1);
for(int i=1;i<=len;++i){
// Multiple strings hash It can be pretreated
bas1[i]=(bas1[i-1]*p1)%mod1;
bas2[i]=(bas2[i-1]*p2)%mod2;
}
for(int i=1;i<=len;++i){
has1[i]=(has1[i-1]*p1+s[i])%mod1;
has2[i]=(has2[i-1]*p2+s[i])%mod2;
}
}
ll gethash1(int r,int len){
// Return to r End length len The string of has1 value
return ((has1[r]-has1[r-len]*bas1[len])%mod1+mod1)%mod1;
}
ll gethash2(int r,int len){
// Return to r End length len The string of has2 value
return ((has2[r]-has2[r-len]*bas2[len])%mod2+mod2)%mod2;
ll gethash11(int l,int r){
// The length is r-l+1
return ((has1[r]-has1[l-1]*bas1[r-l+1])%mod1+mod1)%mod1;
}
ll gethash22(int l,int r){
// The length is r-l+1
return ((has2[r]-has2[l-1]*bas2[r-l+1])%mod2+mod2)%mod2;
Open two map Container two pronged , But in the same container, if the hash value of the corresponding main string and the hash value of the mode string , That is, the hash value mapped by the same hash function , To judge the equality of strings according to the equality of hash values
边栏推荐
- I don't care about you. OKR or KPI, PPT is easy for you
- 在寻求人类智能AI的过程中,Meta将赌注押向了自监督学习
- Swagger2 quick start and use
- GUI 应用:socket 网络聊天室
- PMP 考试常见工具与技术点总结
- 挖财帮个人开的证券账户安全吗?是不是有套路
- 不得不会的Oracle数据库知识点(三)
- The difference between objects and objects
- “疫”起坚守 保障数据中台服务“不打烊”
- be based on. NETCORE development blog project starblog - (14) realize theme switching function
猜你喜欢

Cloud dial test helps Weidong cloud education to comprehensively improve the global user experience

【.NET+MQTT】. Net6 environment to achieve mqtt communication, as well as bilateral message subscription and publishing code demonstration of server and client

Is it really possible that the monthly salary is 3K and the monthly salary is 15K?

Print diamond pattern

2-redis architecture design to use scenarios - four deployment and operation modes (Part 2)

Fundamentals of machine learning: feature selection with lasso

What is the GPM scheduler for go?

【.NET+MQTT】.NET6 环境下实现MQTT通信,以及服务端、客户端的双边消息订阅与发布的代码演示

CLP information - how does the digital transformation of credit business change from star to finger?

Software testers, how can you quickly improve your testing skills? Ten minutes to teach you
随机推荐
Introduction to A-frame virtual reality development
Query efficiency increased by 10 times! Three optimization schemes to help you solve the deep paging problem of MySQL
Sequence list and linked list
Who moved my code!
Self study software testing. To what extent can you go out and find a job?
Oracle database knowledge points that cannot be learned (II)
中电资讯-信贷业务数字化转型如何从星空到指尖?
On covariance of array and wildcard of generic type
1-redis architecture design to use scenarios - four deployment and operation modes (Part 1)
The difference between fetchtype lazy and eagle in JPA
How to use AHAS to ensure the stability of Web services?
Day05 表格
A malware detection method for checking PLC system using satisfiability modulus theoretical model
GUI application: socket network chat room
Weekly open source project recommendation plan
[complimentary ppt] kubemeet Chengdu review: make the delivery and management of cloud native applications easier!
Function: find the approximate value of the limit of the ratio of the former term to the latter term of Fibonacci sequence. For example, when the error is 0.0001, the function value is 0.618056.
Struct in linked list
技术实践|线上故障分析及解决方法(上)
机器学习基础:用 Lasso 做特征选择