字符串哈希
具体流程
1.选取两个互质函数b、h(b<h),这里h也可以用unsigned long long等使自然溢出
2.初始化b^n(n=1,2,3...)
3.递推求出哈希值 h[i]=h[i-1]*d+s[i] h[0]=0;
4.注意 s[i]不能为零
T1 寻找主串中匹配串出现的次数
#include<iostream> #include<cstdio> #include<cstring> #include<string> #define ULL unsigned long long using namespace std; const ULL N=1000001; const ULL b=999979; ULL power[N],sum[N]; int T; int main() { power[0]=1; for(int i=1;i<N;++i) power[i]=power[i-1]*b;//预处理 scanf("%d",&T); while(T--){ char s1[N],s2[N]; scanf("%s%s",s1+1,s2+1); int len1=strlen(s1+1),len2=strlen(s2+1); sum[0]=0; for(int i=1;i<=len2;i++) sum[i]=sum[i-1]*b+(ULL)(s2[i]-'A'+1); ULL s=0;//匹配串的哈希值 for(int i=1;i<=len1;i++) s=s*b+(ULL)(s1[i]-'A'+1); int ans=0; for(int i=0;i<=len2-len1;i++) { if(s==sum[i+len1]-sum[i]*power[len1]) ans++; } printf("%d ",ans); } return 0; }
哈希表
T1 图书管理
add 书名 新加入
find 书名 查找 输出yes/no
1.head数组记得要取比模数大!
2.cin>>数组名称读入到空格;gets(数组名称)读入剩余一整行
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int mod1=1e6+3,mod2=1e6+9,pl=47,p2=79,N=30000; int tot=0,nex[N+5],head[mod1+5],end[N+5]; void insert(int x,int y)//哈希表插入操作 邻接表 { nex[++tot]=head[x]; head[x]=tot; end[tot]=y; } int query(int x,int y) { for(int i=head[x];i;i=nex[i]) { if(end[i]==y) return 1; } return 0; } int main() { int n; scanf("%d",&n); while(n--) { char s[205],op[10]; cin>>op; gets(s); int len=strlen(s); int sum1=0,sum2=0; for(int i=0;i<len;i++) { sum1=(sum1*pl+s[i])%mod1; sum2=(sum2*p2+s[i])%mod2; }//双哈希 if(op[0]=='a') insert(sum1,sum2); else { if(query(sum1,sum2)) printf("yes "); else printf("no "); } } return 0; }