• 【数据结构】哈希


    知识点

    一 . 字符串哈希函数构造 


    一 . 字符串哈希函数构造 

    字符串哈希通过牺牲很小的准确率,达到快速进行字符串匹配的效果 

    例题: 洛谷 P3370 【模板】字符串哈希

    题目描述

    如题,给定 N 个字符串(第 i 个字符串长度为 M_i,字符串内包含数字、大小写字母,大小写敏感),请求出 N 个字符串中共有多少个不同的字符串。

    输入格式

    第一行包含一个整数 N,为字符串的个数。

    接下来 N 行每行包含一个字符串,为所提供的字符串。

    输出格式

    输出包含一行,包含一个整数,为不同的字符串个数。

    输入输出样例

    输入 #1

    5
    abc
    aaaa
    abc
    abcc
    12345

    输出 #1

    4

    说明/提示

    对于 30% 的数据:N\leqslant 10M_i \approx 6M_{max}\leqslant 15

    对于 70% 的数据:N\leqslant 1000M_i \approx100M_{max}\leqslant 150

    对于 100% 的数据:N\leqslant 10000M_i\approx 1000M_{max} \leqslant 1500

     处理方法1:自然溢出法

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define ll unsigned long long
    6. using namespace std;
    7. int n;
    8. const int maxn=1e7+5,base=131; //base表示进制数
    9. const ll int mod=19260817891;
    10. ll int a[maxn]; //a[]即哈希表
    11. int res=0;
    12. char s[maxn];
    13. inline ll int hash_check(char s[])
    14. {
    15. ll int len=strlen(s),ans=0;
    16. for(int i=0;i
    17. {
    18. ans=ans*base+(ll)s[i]; //利用自然数溢出,即超过2*64自动溢出,节省时间
    19. }
    20. return ans;
    21. }
    22. int main()
    23. {
    24. scanf("%d",&n);
    25. for(int i=1;i<=n;++i)
    26. {
    27. scanf("%s",s);
    28. a[i]=hash_check(s);
    29. }
    30. sort(a+1,a+n+1);
    31. for(int i=1;i<=n;++i)
    32. {
    33. if(a[i]!=a[i+1]) res++;
    34. }
    35. printf("%d",res);
    36. return 0;
    37. }

    方法2:单hash表

    该题与自然溢出唯一不同的地方是:在进行散列的时候,与一个很大的整数进行取模。

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define ll unsigned long long
    6. using namespace std;
    7. int n;
    8. const int maxn=1e7+5,base=131;
    9. const ll int mod=19260817891;
    10. ll int a[maxn];
    11. int res=0;
    12. char s[maxn];
    13. inline ll int hash_check(char s[])
    14. {
    15. ll int len=strlen(s),ans=0;
    16. for(int i=0;i
    17. {
    18. ans=(ans*base+(ll)s[i])%mod; //唯一的不同之处
    19. }
    20. return ans;
    21. }
    22. int main()
    23. {
    24. scanf("%d",&n);
    25. for(int i=1;i<=n;++i)
    26. {
    27. scanf("%s",s);
    28. a[i]=hash_check(s);
    29. }
    30. sort(a+1,a+n+1);
    31. for(int i=1;i<=n;++i)
    32. {
    33. if(a[i]!=a[i+1]) res++;
    34. }
    35. printf("%d",res);
    36. return 0;
    37. }

  • 相关阅读:
    Java基础抽象类详解
    传输层 知识点总结
    Linux中FTP安装
    (翻译)JavaFX高级教程:JavaFX2.0的FXML语言
    深入理解Docker:简化部署与管理的利器
    [SpringBoot]配置文件①(配置文件格式、yaml配置及读取)
    Golang学习之路6-goroutine并发
    英国消费“避之不及”,东南亚“爱不释手”,TikTok Shop为何?
    GBase 8s是否支持同城复制
    下载文件时的文件名中文乱码问题,文件名丢失
  • 原文地址:https://blog.csdn.net/gzkeylucky/article/details/126810509