首页 > 其他分享 >洛谷题单指南-集合-P3370 【模板】字符串哈希

洛谷题单指南-集合-P3370 【模板】字符串哈希

时间:2024-03-20 14:59:47浏览次数:31  
标签:int 洛谷题 整数 hashcode vector 哈希 字符串 P3370

原题链接:https://www.luogu.com.cn/problem/P3370

题意解读:本题要求理解哈希的原理,自行建立哈希表解题,如果直接使用map,就不推荐。

解题思路:

先介绍哈希的原理

1、什么是哈希?什么是哈希表?

先从一个问题出发:给定不超过105个整数(取值1~109),要统计不重复整数的数量。

首先,如果取值范围是1~105,可以借助计数排序的思想,定义数组int a[N],N在1e5规模,遍历所有整数,对出现的整数标记a[i] = 1,最后统计>0的个数;

但是,由于取值范围是1~109,如果定义数组int a[N],N在1e9规模,内存会爆掉,能不能用更小的数据结构来搞定呢?

可以定义vector<int> a[M],M在1e5规模内即可

对于每一个整数i,先计算i % M,取模之后必然落到[0~M)区间,然后将i存入a[i % M].push_back(i)

在存入i之前,可以判断a[i % M]这个vector里是否已经存在了i,存在则不加入

最后,遍历所有a[k],累加a[k].size()即得不重复的整数数量。

把一个大的整数映射到一个小整数的过程叫做哈希,如i % M;

用来存储元素的vector<int> a[M]则称为哈希表

2、字符串如何哈希?

字符串也可以转化为整数,只需把字符串当做p进制数来处理即可

例如:ABC,转成数字:'A' * p2 + 'B' * p1 + 'C' * p0

再对一个合适的M取模:('A' * p2 + 'B' * p1 + 'C' * p0) % M

就完成了字符串的哈希

通常:P取一个素数会减少冲突,常见选择如:131、13331

M则根据实际数据量进行选择即可。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 10005, M = 10000, P = 131;

vector<string> h[N];
int n, ans;
string s;

int main()
{
    cin >> n;
    while(n--)
    {
        cin >> s;
        int hashcode = 0;
        for(int i = 0; i < s.size(); i++)
        {
            hashcode = (hashcode * P + s[i]) % M; //类似二进制转十进制的操作计算hashcode,每次都要%M以免溢出
        }
        bool exist = false; //s是否已经存在
        for(int i = 0; i < h[hashcode].size(); i++) //在h[hashcode]中查找s是否存在
        {
            if(h[hashcode][i] == s)
            {
                exist = true;
                break;
            } 
        }
        if(!exist)
        {
            h[hashcode].push_back(s); //如果s不存在则添加
            ans++;
        } 
    }
    cout << ans;

    return 0;
}

 

标签:int,洛谷题,整数,hashcode,vector,哈希,字符串,P3370
From: https://www.cnblogs.com/jcwy/p/18085205

相关文章

  • 洛谷题单指南-集合-P1536 村村通
    原题链接:https://www.luogu.com.cn/problem/P1536题意解读:城镇之间现有的道路关系可以将城镇划分的若干集合,每个集合内的城镇是互通的,要计算最少增加多少条道路,使得每个集合都相通。解题思路:利用并查集,统计一共出现多少个集合,即p[i]=i的数量,最少的道路数即集合数-1,即可把所......
  • 洛谷题单指南-集合-P1551 亲戚
    原题链接:https://www.luogu.com.cn/problem/P1551题意解读:要判断两人是否是亲戚,只需要看两人是否属于一个集合,基于所有已知的亲戚关系,可以建立多个有亲戚关系的集合,这个过程可以借助并查集。解题思路:并查集:1、定义并查集是一种树形数据结构,本质上是多棵树,每棵树表示一个集合,......
  • 哈希技术解析:从哈希函数到哈希桶迭代器的全面指南
    文章目录引言一、哈希表与哈希函数1、哈希表的基本原理2、哈希函数的作用与特点3、哈希冲突的处理方法二、哈希桶及其迭代器1、哈希桶a.定义哈希桶结构b.哈希函数c.哈希桶的插入、查找、删除2、哈希桶的迭代器a.类型定义与成员变量b.构造函数c.解引用与比较操作d.递......
  • 洛谷题单指南-二叉树-P1185 绘制二叉树
    原题链接:https://www.luogu.com.cn/problem/P1185题意解读:在表格中绘制二叉树,有几个关键点1、结点用小写字母o 表示,对于一个父亲结点,用 / 连接左子树,用 \连接右子树,表格其余地方填空格。2、第m层结点若两个属于同一个父亲,那么它们之间由 3个空格隔开;若两个结点相邻但......
  • 洛谷题单指南-二叉树-P3884 [JLOI2009] 二叉树问题
    原题链接:https://www.luogu.com.cn/problem/P3884题意解读:要计算二叉树的深度、宽度、节点间的距离,深度、宽度的概念很好理解,节点间的距离描述是:节点u,v之间的距离表示从u到v的最短有向路径上向根节点的边数的两倍加上向叶节点的边数。说人话就是:u到v的距离=uv最近公共祖先到u......
  • Offer必备算法14_哈希表_五道力扣题详解(由易到难)
    目录①力扣1.两数之和解析代码②力扣面试题01.02.判定是否互为字符重排解析代码③力扣217.存在重复元素解析代码④力扣219.存在重复元素II解析代码⑤力扣49.字母异位词分组解析代码本篇完。①力扣1.两数之和1.两数之和难度简单给定一个整数数组 nu......
  • 哈希冲突
    来看一下一般的根号算法的思路过程,见这篇题解重点是这句话所以一般来说,我们先写出最暴力的版本,然后考虑是否可以根号算法优化那为什么我们要设置\(dp\)数组呢?其实这里仍然运用了转换对象法这个思想,因为每次修改的数只有一个,但是模数却有很多个,所以我们可以尝试去统计贡献......
  • 8--哈希表Hash的相关操作
    哈希表(Hashtable)是一种数据结构,用于实现键值对的存储和查找。其中直接地址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法都可以作为哈希表的散列函数。直接地址法是唯一一个不会产生冲突的方法,因为它是线性的,每一个数都有对应的地址,所有就不会产生冲突,但是空间......
  • 洛谷题解 - B3850 [GESP202306 四级] 幸运数
    目录题目描述输入格式输出格式样例#1样例输入#1样例输出#1代码题目描述小明发明了一种“幸运数”。一个正整数,其偶数位不变(个位为第111位,十位为第......
  • 洛谷题单指南-二叉树-P1030 [NOIP2001 普及组] 求先序排列
    原题链接:https://www.luogu.com.cn/problem/P1030题意解读:已知中序、后序,求先序。解题思路:与洛谷题单指南-二叉树-P1827[USACO3.4]美国血统AmericanHeritage非常类似,不在介绍过程,直接给出代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;stringin,post......