【模板】字符串哈希

来源:互联网 发布:手感好的键盘 知乎 编辑:程序博客网 时间: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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 uc屏蔽了一个网站怎么办 uu跑腿送货遇到不方便收货怎么办 雷神加速器忘记暂停怎么办 obs直播开摄像头吃鸡掉帧怎么办 陌陌收到的礼物怎么办 吃了油腻的东西恶心怎么办 主播工资不发怎么办 主播工资被欠怎么办 直播平台不发工资坑主播怎么办 主播公司不发工资怎么办 梦幻月卡用完了怎么办 网易星球实名认证通过不了怎么办 认证过荔枝主播怎么办 苹果手机相机不对焦怎么办 苹果手机摄像头不能对焦了怎么办 闪电邮里面邮件太多怎么办 苹果手机和助理打不开怎么办 苹果我的世界打不开怎么办 ps试用7天到期了怎么办 皮肤锁不住水份怎么办 硫酸弄到皮肤上怎么办 直播时图像反看怎么办 快手直播权限被收回怎么办 快手直播权限被收回了怎么办 腾讯手游助手玩游戏卡怎么办 电脑直播视频打不开了怎么办 平板进水开不了机怎么办 苹果平板进水开不了机怎么办 苹果平板电脑进水了怎么办 电脑换主机以前的文件怎么办 货车卖了没过户怎么办 微交易出金不了怎么办 直播时出现央视影音客户端怎么办 qq账号暂时无法登录怎么办 饿了吃东西胃疼怎么办 早上不吃饭胃疼怎么办 孕晚期胃疼呕吐怎么办 胃疼了一晚上怎么办 微信视频图像倒立怎么办 ps链接图层锁定怎么办 慕课过时间了怎么办