【模板】字符串哈希
来源:互联网 发布:手感好的键盘 知乎 编辑:程序博客网 时间:2024/06/11 17:48
题目描述
如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。
输入输出格式
输入格式:
第一行包含一个整数N,为字符串的个数。
接下来N行每行包含一个字符串,为所提供的字符串。
输出格式:
输出包含一行,包含一个整数,为不同的字符串个数。
输入输出样例
输入样例#1:
5
abc
aaaa
abc
abcc
12345
输出样例#1:
4
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,Mi≈6,Mmax<=15;
对于70%的数据:N<=1000,Mi≈100,Mmax<=150
对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500
样例说明:
样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。
简要思路:1.可用“拉链法”解决哈希冲突问题,通过哈希函数得到字符串关键值,然后查询。若不存在与已有信息中,则ans++,讲当前字符串加入已有信息。详细见代码1。
2.利用trie树,APhash。比较两个hash值再判断。注意结构体比较要重载运算符。详见代码2。
代码1(link):
#include<iostream>#include<string>#include<cmath> using namespace std;int n,ans=0,cnt=0;string a,data[10007];int list[10001]={0};int next[10001]={0};int ok(string h){ int sum=0; for(int i=0;i<h.size();i++)sum=sum*33+h[i]; sum=abs(sum%10007); int u=list[sum]; while(u) { if(data[u]==h)return 0; u=next[u]; } cnt++; data[cnt]=h; next[cnt]=list[sum]; list[sum]=cnt; return 1;}int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>a; if(ok(a))ans++; } cout<<ans<<endl; return 0; }
代码2(trie+APhash):
#include <cstdio>#include <cstring>using namespace std;typedef unsigned long long ull;struct node{ ull h1,h2; int l,r;};char ch[1505];int n,tot,len;node tree[10005];ull hash1(char ch[],int len)//自然溢出算法{ if(!len) return 0; ull ans=0; for(int i=0;i<len;i++) ans=ans*131+ch[i]; return ans;}ull hash2(char ch[],int len)//APhash算法{ if(!len) return 0; ull ans=0; for(int i=0;i<len;i++) if(i&1) ans^=((ans<<7)^ch[i]^(ans>>3)); return ans;}bool operator <(const node &a,const node &b){ if(a.h1!=b.h1) return a.h1<b.h1; return a.h2<b.h2;}bool operator ==(const node &a,const node &b){ return (a.h1==b.h1)&&(a.h2==b.h2);}bool operator >(const node &a,const node &b){ return !(a<b)&&!(a==b);}void finds(int x){ if(tree[x]==tree[tot]){ tot--; return; } if(tree[tot]>tree[x]){ if(tree[x].r) finds(tree[x].r); else tree[x].r=tot; return; }; if(tree[x].l) finds(tree[x].l); else tree[x].l=tot;}int main(){ scanf("%d",&n); scanf("%s",ch),len=strlen(ch),tree[++tot].h1=hash1(ch,len),tree[tot].h2=hash2(ch,len); for(int i=2;i<=n;i++) scanf("%s",ch),len=strlen(ch),tree[++tot].h1=hash1(ch,len),tree[tot].h2=hash2(ch,len),finds(1); printf("%d",tot);}
`
0 1
- 字符串哈希模板
- 【模板】字符串哈希
- 【模板】 字符串哈希
- [模板]-字符串哈希
- 【模板】字符串哈希
- P3370 【模板】字符串哈希
- HDU4821-字符串哈希模板
- P3370 【模板】字符串哈希
- P3370 [模板] 字符串哈希
- [P3370][模板]字符串哈希
- ACM hash哈希字符串 模板 hdu4080
- 字符串哈希(Hash模板)
- 洛谷 P3370 【模板】字符串哈希
- 【模板】【洛谷P3370】字符串哈希
- [模板]字符串哈希的简易做法
- 洛谷3370字符串哈希模板
- 洛谷P3370 【模板】字符串哈希
- 字符串哈希-P3370 【模板】字符串哈希
- 二叉树链表表示法
- ROS学习(四)机器人的移动与矫正
- 十六周—结构体练习
- SHA-256算法实现
- 我的下载资源整理(持续更新)
- 【模板】字符串哈希
- Java中常用的比较器Comparable与Comparator
- linux基础命令——文本编辑vim
- opencv计算机视觉学习笔记六
- onvif代码框架的生成
- 直接插入排序
- 查找在线主机的 IP 地址,让对方无处遁形!
- 【STL】迭代器
- UVa 502 - DEL command