hash表又叫散列表,是一种用来存放数据的数据结构。用于快速查询

hash表就是一种数组,输入关键字,通过hash函数得到,对应数据的下标。(hash值就是下标)

hash函数根据关键字设计,主要原理:依据数组的大小求模运算

数组大小一般设计为质数,以便均匀散布。

解决hash冲突:关键在于找空位置

  1. 链表:结构体内加入next指针。当取模结果相同,数据不同时(即哈希冲突),将数据存放于next里面。
  2. 开发地址:1.线性探测法,当发生冲突时,往后面一个一个的找空位置+1+1。                                           2.平方探测法,发生冲突,往i的平方找,+i^2 ,相比线性减少了数据扎堆                               3.双hash,第二个hash的mod要取比数组大小要小的质数,hash2(key)  =mod-(key%mod),hash的结果不会等于0。往后移hash2。

hash表快满了,进行再hash,建一个新表,尺寸为2倍以上,并将数据迁移。

缺点:1.冲突   2.表越满,性能越差


P1102 A-B 数对 https://www.luogu.com.cn/problem/P1102

思路:建立hash表 ,存放数据还有它出现的次数,通过链表解决冲突。从第一个开始遍历,hash得出a[i]+c在表中的位置,得到出现次数。

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=200003;
ull a[200000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[200000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;          }if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}

 本应通过链表解决冲突,但依据测试结果应该是没有完全解决,这里我不明白,或许是我链表写错了

然后就把数组开大一点,就过了

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=1000003;
ull a[1000000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[1000000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;          }if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}

P2580 于是他错误的点名开始了https://www.luogu.com.cn/problem/P2580

思路:和上面那题一样,建表。然后依据输入查表

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
int base=131;
int mod=1000007;
int hashh(char* str)
{int len=strlen(str);int ans=0;for(int i=0;i<len;i++){ans=(ans*base+(int)str[i])%mod;}return ans;
}struct arr{char str[50]={'\0'};int time=0;arr* next;
}htable[1000006];
int main()
{int n;scanf("%d",&n);getchar();char str[55];for(int i=0;i<n;i++){scanf("%s",str);arr* p=htable+hashh(str);while(strcmp(p->str,str)!=0&&p->str[0]!='\0'){if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;p->next=NULL;}strcpy(p->str,str);}int m;scanf("%d",&m);getchar();for(int i=0;i<m;i++){scanf("%s",str);arr* p=htable+hashh(str);while(strcmp(p->str,str)!=0&&p->next!=NULL){p=p->next;} if(strcmp(p->str,str)==0){if((p->time)++==0) printf("OK\n");else printf("REPEAT\n");}else printf("WRONG\n");}return 0;
}

二次编辑

上面链表的问题,我已经找到

就是在遍历链表的时候,遍历一个会将下一个地址赋为NULL,导致链断了。两道题目都有这个问题,这里就只放第一个的代码了

订正

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull mod=200003;
ull a[200000+5];
ull hashh(ull num)
{return num%mod;
}
struct arr{ull num=0;ull time=0;arr* next;
}htable[200000+5];int main()
{int n;ull c;scanf("%d%lld",&n,&c);for(int i=0;i<n;i++){scanf("%lld",&a[i]);arr* p=htable+hashh(a[i]);//找到这个hash值对应的地址while(p->num!=a[i]&&p->time>0)//如果这个位置已经被占了即次数大于01也不等于a[i]{if(p->next==NULL) p->next=(arr*)malloc(sizeof(arr));p=p->next;}p->next=NULL;p->num=a[i];p->time++;}ull ans=0;ull t;for(int i=0;i<n;i++){t=c+a[i];//接下来看t出现的次数arr* p=htable+hashh(t);while(p->num!=t&&p->next!=NULL){p=p->next;          }if(p->num==t){ans+=p->time;}}printf("%lld",ans);return 0;
}

hash表(学习笔记)相关推荐

  1. Windows句柄表学习笔记 —— 句柄表全局句柄表

    Windows句柄表学习笔记 -- 句柄表&全局句柄表 句柄表 实验一:在WinDbg中查看句柄表 第一步:打开一个Win32窗口程序 第二步:编译并运行以下代码 第三步:查看运行结果 第四步 ...

  2. [OfficeExcel] 王佩丰老师OfficeExcel2010 5-6 讲 数据有效性与数据透视表 学习笔记

    王佩丰老师OfficeExcel2010 学习笔记 Excel分类汇总和数据有效性 Excel 数据透视表 视频链接: link. Excel分类汇总和数据有效性 分地区统计金额的总计:使用分类汇总前 ...

  3. 数据结构基础:线性表学习笔记

    1.线性表定义 线性表是指n个元素的有限序列(n>=0),通常用(a1,a2,a3...,an),来表示. 2.线性表特点 1.存在唯一的一个首元素 2.存在唯一一个尾元素 3.除第首元素外,每 ...

  4. 数据结构第二章线性表学习笔记

    1.    C++程序设计模板   (关于template的解释)[以下内容摘自百度] 函数声明格式 template <class(或typename) any(或任意符合规则的名称)> ...

  5. LCA RMQ+ST表学习笔记

    RMQ RMQ问题:在给定的一个长度位N的区间中,有M个询问,每次询问给出区间[L,R],求出区间段元素的 最大值/最小值.对于RMQ问题很容易想到遍历的做法,将区间[L,R]中的元素遍历一遍,即可寻 ...

  6. CUUG 外部表学习笔记

    oracle 外部表 一.创建外部表以及产生 1.创建一个directory,需要有create any directory权限 create directory ext as 'D:/'; 2.赋予 ...

  7. MySQL-SQL简介、管理逻辑库和数据表-学习笔记04

    零. 命令表 这篇文章比较长,出现的命令比较多.在这里先将本文出现的命令总结一下 类 命令 解释 注释 # 这是一段注释,/*这也是一段注释*/ 注释的方法 逻辑库 CREATE DATABASE d ...

  8. python hash表_python数据结构与算法——哈希表

    哈希表 学习笔记 参考翻译自:<复杂性思考> 及对应的online版本:http://greenteapress.com/complexity/html/thinkcomplexity00 ...

  9. Unity3d之HashSlash学习笔记之(二)--角色基础类的构建

    Hash&Slash学习笔记之(二)--角色基础类的构建 BaseStat类的构建 基本成员变量: _baseValue //基础属性值 _buffValue //增加的buff值 _expT ...

  10. 数据结构学习笔记(七):哈希表(Hash Table)

    目录 1 哈希表的含义与结构特点 1.1 哈希(Hash)即无序 1.2 从数组看哈希表的结构特点 2 哈希函数(Hash Function)与哈希冲突(Hash Collision) 2.1 哈希函 ...

最新文章

  1. 【商务智能】商务智能 ( 概念 | 组成 | 过程 )
  2. camvid数据集介绍_fastai 官方教程之查看数据
  3. boost::signals2模块实现多线程信号调用基准的测试程序
  4. postman websocket_新型开源postwoman接口调试工具VS传统经典postman和crapAPI工具
  5. 在WildFly 8.2中修补焊接3 – Java EE 8的第一个实验RI
  6. 在JupyterNotebook中使用多个Python环境
  7. RefreshLayout刷新组件,有详细注释适合使用和中高端学习
  8. html标签的pre语义,HTML pre 标签
  9. 利用Visio绘制网络拓扑图要注意些什么
  10. SCP使用技巧-递归排除文件
  11. Mail.Ru Cup 2018 Round 2: D. Refactoring(模拟+KMP)
  12. Tomcat 8 中的startup.bat
  13. Linux检查服务器cpu状态脚本,Linux服务器硬件运行状态及故障邮件提醒的监控脚本分享...
  14. sysbench和lua的简单研究
  15. 英语单词APP开发功能需求
  16. 千村示范、万村整治 浙江
  17. UE4_Stereo Panoramic Movie Capture_合并左右眼为一张图片
  18. singleton pattern的一个模板实现, 适用于单线程, 并且提供了Release方法
  19. flask爱家租房项目开发(一)
  20. GitHub 近两万 Star,无需编码,可一键生成前后端代码,这个开源项目有点强!...

热门文章

  1. 微软word如何插入页码_如何在Microsoft Word中使用页码
  2. sklearn使用入门
  3. sklearn常用工具
  4. 数据的计算(大数据)
  5. 服务监控CAT的使用
  6. Java初学者作业——编写Java程序, 实现根据用户购买商品总金额, 计算实际支付的金额及所获得的购物券金额。
  7. 如何确认软件测试结束
  8. java if中的continue_java中break和continue源码解析
  9. 关于@ComponentScan 的使用 和springboot启动类所在位置的关系
  10. 建立良好体验度的Web注册系统