目录

  • 谁是你的潜在朋友 【★】
  • 是唯一的 【★】
  • 字符串减法 【★★】
  • 分组统计【★★★】

在哈希这一块常用的问题包括:判断<=105个正整数中某m个正整数是否出现过、出现了多少次——声明bool/int hashTable[maxn] = {false}/{0}。其做法本质是直接将输入的整数作为数组的下标来对这个数的性质进行统计,即hash(key)=key直接定址,是最常见也最实用的散列应用。复杂一点还有二次映射。把这两个思想掌握了就差不多了。
本篇文章有的内容来自 https://blog.csdn.net/myRealization/article/details/80154726

谁是你的潜在朋友 【★】

http://codeup.cn/problem.php?cid=100000582&pid=0

  • 题目描述
    “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男,你发现自己与他人相互了解的机会 并不太多。幸运的是,你意外得到了一份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。
    首先你对借阅记录进行了一番整理,把N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。

  • 输入
    每个案例第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i = 1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)

  • 输出
    每个案例包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^)

样例输入
4 5
2
3
2
1
样例输出
1
BeiJu
1
BeiJu

用数组做下标,直接定址hash

#include<cstdio>
int main(void)
{int M,N;int i;while(scanf("%d%d",&N,&M)!=EOF){int a[M+1]={0};int student[N+1]={0};for(i=1;i<=N;i++){scanf("%d",&student[i]);a[student[i]]++;}for(i=1;i<=N;i++){if( (a[student[i]]-1) == 0 ){printf("BeiJu\n");continue;}printf("%d\n",a[student[i]]-1);}}return 0;
}

是唯一的 【★】

  • 题目描述
    对火星上的人们来说,独特是如此重要,以至于他们的彩票也是以一种独特的方式设计的。获胜的规则很简单:一次下注是从[1,104]中选择一个数字。第一个押注于唯一号码的人获胜。例如,如果有7人在5 31 5 88 67 88 88 17上下注,那么第二个押注31的人就赢了。
  • 输入
    每个输入文件包含一个测试用例。每一种情况都包含以正整数N开头的一行(N<=105),然后是N次下注。数字用空格分隔。
  • 输出
    对于每个测试用例,用一行打印获胜号码。如果没有赢家,则打印“无”。
样例输入
7 5 31 5 88 67 88 17
5 888 666 666 888 888
样例输出
31
None

用数组做下标,直接定址hash

#include<cstdio>
int a[10005];
int main(void)
{int N;int i;int flag;while(scanf("%d",&N)!=EOF){flag=0;int student[N+1]={0};for(i=1;i<=N;i++){scanf("%d",&student[i]);a[student[i]]++;}for(i=1;i<=N;i++){if( a[student[i]] == 1 ){printf("%d\n",student[i]);flag=1;break;}}if(!flag){printf("None\n");}}return 0;
}

字符串减法 【★★】

  • 题目描述
    给定两个字符串S1和S2,S=S1-S2定义为S中所有字符之后的剩余字符串。2来自S1。你的任务只是计算S1-S2对于任何给定的字符串。然而,做这件事可能并不那么简单。快地.
  • 输入
    每个输入文件包含一个测试用例。每个案例包含两行,给出S1和S2分别。这两个字符串的字符串长度不超过10。4。保证所有字符都是可见的ASCII代码和空格,一个新的行字符表示字符串的结束。
  • 输出
    对于每个测试用例,打印S1-S2一条线。
样例输入
They are students.
aeiou
样例输出
Thy r stdnts.

用数组做下标,直接定址hash

#include<cstdio>
#include<cstring>
char s1[1005],s2[1005];
bool hush[130]={false};
int main(void)
{int i=0;while( gets(s1) != NULL){gets(s2);for(i=0;i<strlen(s2);i++){hush[s2[i]]=true;//确定重复}for(i=0;i<strlen(s1);i++){if(hush[s1[i]]==false)printf("%c",s1[i]);}}return 0;
}

分组统计【★★★】

  • 题目描述
    先输入一组数,然后输入其分组,按照分组统计出现次数并输出,参见样例。

  • 输入
    输入第一行表示样例数m,对于每个样例,第一行为数的个数n,接下来两行分别有n个数,第一行有n个数,第二行的n个数分别对应上一行每个数的分组,n不超过100。

  • 输出
    输出m行,格式参见样例,按从小到大排。

样例输入
1
7
3 2 3 8 8 2 3
1 2 3 2 1 3 1
样例输出
1={2=0,3=2,8=1}
2={2=1,3=0,8=1}
3={2=1,3=1,8=0}

解析:这一道题目可以说是集整数哈希思想于大成,值得仔细分析。

  • 首先,题目中说输入的数据量不超过100,类别同样不超过100,但是没有说数据的具体范围,可能会在整数作为数组的下标超过数组下标范围,理论上来说,对于这种题目,以空间换时间,要求数据应该不超过106。因此,统计输入的数据和组别是否已经出现,可以开hashTable[100100]这样大。
  • 去重操作。在有了标识数据是否出现的哈希表的情况下,可以很简单的做到。
    答案矩阵是一个二次映射的二维数组,可以直接通过组别和数据查到相应组别的数据出现的次数。
    出现50%错误:如果二维数组开的太小,很容易溢出,所以记录第一行数据中最大的值,将其+10作为二维数组中的列数即可解决。

思路:

  1. 输入第一行数据,存入data[]中,同时使用hashTable1[]去重,将去重后的数存入nums[]中,并排序。
  2. 输入第二行组别,存入group[]中,同时使用hashTable2[]函数去重,将去重后的数存入g[]中,并排序。
  3. 同时,将group[]和data[]对应映射到ans[][]中,ans[i][j]中i为分组,j为数。a[i][j]为第i组的j数出现的次数。
  4. 遍历输出。
说白了就是用一个数组输入第一行的数。
再用一个数组保存去重后的数。然后排序。第二行也是同理的。
最后用一个映射的二维数组统计出现的次数。

用数组做下标,直接定址hash,和二次映射的hash

#include <cstdio>
#include <algorithm>
using namespace std;int main() {int m;scanf("%d", &m);while (m--) {int n, maxCol = 0, data[110], group[110]; //分别记录输入的数据和分组scanf("%d", &n);//nums记录输入的数据去重后的数据  int nums[120], len1 = 0;//使用哈希表对data进行存在标识, 以便去重 bool hashTable1[100100] = {false}; for (int i = 0; i < n; i++) { scanf("%d", &data[i]);      //边录入边去重 if (!hashTable1[data[i]]) { //如果这个数据尚未被记录 nums[len1++] = data[i]; hashTable1[data[i]] = true; }//得到最大的数, 方便答案直接映射而不溢出 if (maxCol < data[i]) maxCol = data[i];  } sort(nums, nums + len1); //数据从小到大存放在nums中, 无重复  //g记录输入的组别去重后的数据  int g[120], len2 = 0; //使用哈希表对group进行存在标识, 以便去重bool hashTable2[100100] = {false};/*二维答案表,元素ans[g[i]][nums[j]]表示g[i]组中对应的nums[j]出现的次数 ans[i][j], i为分组, j为数, a[i][j]为第i组的j数出现的次数 */int ans[n + 10][maxCol + 10] = {0};  for (int i = 0; i < n; i++) {scanf("%d", &group[i]);ans[group[i]][data[i]]++; if (!hashTable2[group[i]]) { //如果这个组别尚未被记录 g[len2++] = group[i];  hashTable2[group[i]] = true;} }sort(g, g + len2); //组别从小到大存放在g中, 无重复 //输出结果 for (int i = 0; i < len2; i++) {printf("%d={", g[i]);for (int j = 0; j < len1; j++) {printf("%d=%d", nums[j], ans[g[i]][nums[j]]);if (j < len1 - 1) printf(",");else printf("}\n");}} }return 0;
}

散列(hash)练习题相关推荐

  1. 目前常见的散列(Hash)算法

    目前常见的散列(Hash)算法 算法名称 输出大小(bits) 内部大小 区块大小 长度大小 字符尺寸 碰撞情形 HAVAL 256/224/192/160/128 256 1024 64 32 是 ...

  2. 【常用算法】散列(hash)

    散列(hash)定义 将元素通过一个函数(H(key))转换为整数,使得该整数可以尽量唯一的代表这个元素 散列最基本的对应关系就是对应其本身H(key)=key(很常用) 先看一个简单的问题 随机给一 ...

  3. 手撸数据结构之线性链表---哈希表(散列) Hash

    哈希数据结构 哈希表的存在是为了解决能通过O(1)时间复杂度直接索引到指定元素. 这是什么意思呢?通过我们使用数组存放元素,都是按照顺序存放的,当需要获取某个元素的时候,则需要对数组进行遍历,获取到指 ...

  4. AcWing 840. 模拟散列表(散列hash)

    题目连接 https://www.acwing.com/problem/content/description/842/ 思路 使用开放寻址法,思路大概是这样我们讲要查询的数模上一个大于n的质数,然后 ...

  5. 散列(哈希 hash)

    目录 前言 hash介绍 字符串hash初步 练习题 前言 散列(hash)是常用的算法之一. 为了了解hash我们先看一个简单的题. 题目: 给出N个正整数,再给出M个正整数,问这M个数中的每个数分 ...

  6. 聊聊传说中的散列哈希Hash算法,以及Java中的HashTable,HashMap,HashSet,ConcurrentHashMap......

    建议本文结合java源码来阅读,看了之后就什么都懂了,还有参考文献. 散列(Hash) 是一种按关键字编址的存储和检索方法 散列表(HashTable)根据元素的关键字确定元素的位置 散列函数(Has ...

  7. mysql 散列存储_什么是数据库散列存储? - 蚂蚁吞大象的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...

    什么是数据库散列存储? 上一篇 / 下一篇  2012-11-30 17:25:03 / 个人分类:数据库 (转载自百度空间http://hi.baidu.com/pplboy/item/2d7a26 ...

  8. 《数据库系统概念》14-静态散列

    2019独角兽企业重金招聘Python工程师标准>>> 顺序文件组织的缺点之一是必须通过访问索引或使用二分法搜索来定位数据,这需要较多的I/O操作.基于散列技术的文件组织方式则不需要 ...

  9. 06-散列(Hash)基础分析

    文章目录 散列(Hash)基础分析 什么是散列表? 如何理解散列设计? 如何解决散列冲突? Java中散列应用分析与实践? 如何对散列(Hash)函数进行设计? 数据插入时线性探测过程是怎样的? 开放 ...

最新文章

  1. MaxScale:实现MySQL读写分离与负载均衡的中间件利器
  2. java 班级号_Java 学校班级回忆录网站管理系统
  3. DIY混合BCI刺激系统:SSVEP-P300 LED刺激
  4. 运营人必备的7大技能:数据分析能力是未来运营的分水岭
  5. python 权限管理 mongodb_MongoDB为用户设置访问权限
  6. python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹
  7. mysql query sql_sql:query 标签
  8. PyCharm怎么关闭端口,解决端口占用问题
  9. java实现键盘输入_java 键盘输入的多种实现方法
  10. Animation in Windows 8 apps
  11. Linux学习之旅(二)Linux文档操作
  12. BI系统AWS云迁移方案设计(通用)
  13. 邻接矩阵实现(有向邻接矩阵)、(无向邻接矩阵) 基于C++
  14. 佳蓝php智能应答系统|在线客服 v1.0,佳蓝PHP智能应答系统|在线客服 v1.0
  15. cppcheck 自定义规则_CppCheck介绍与使用
  16. python计算图像面积_利用图像处理计算叶片面积
  17. 【Python爬虫】:模拟登录QQ空间
  18. 这次的PION的总结
  19. 【Posts阅读】关于 Deep Sets 和 Neural Processes的简单介绍
  20. 最短路小结(三种算法+各种常见变种)

热门文章

  1. Python添加邮件附件并通过邮件发送测试报告
  2. oracle pl/sql 中目录的创建
  3. [leetcode] 22. Generate Parentheses(medium)
  4. JVM——虚拟机的简介【摘录】
  5. The difference between sleep(), wait(), and yield() in human terms.
  6. STM32 SPI难点浅析
  7. 机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测
  8. C++ Primer 5th笔记(chap 18 大型程序工具)虚继承
  9. 区块链BaaS云服务(31) 吉利 Concordium区块链
  10. java元婴期(22)----java进阶(mybatis(1)---mybatis框架概述入门程序)