初学哈希表(C++)

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

我的理解的哈希表就是一种查找数据非常方便的数据结构。

  • 哈希表实现方法

开放寻址法:将所有数据放进一个比数据范围大的数组里,每个数据的关键码值是用对特殊值取模得到的。

//拉链法
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100003;
int h[N],e[N],ne[N],idx;

void insert(int x)
{
	int k = (x%N+N)%N;
	
	e[idx] = x,ne[idx] = h[k] ,h[k] = idx++;
}

bool find(int x)
{
	int k = (x%N+N)%N;
	for(int i=h[k];i!=-1;i=ne[i])
		if(e[i] == x) return true;
	
	return false;
}

int main()
{
	int n;
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin >> n;
	memset(h,-1,sizeof h);
	while(n--)
	{
		string op;
		int x;
		cin >> op >> x;
		if(op == "i") insert(x);
		else
		{
			if(find(x)) puts("Yes");
			else puts("No");
		}
	}
	return 0;
}

拉链法:通过一个数组和单链表实现,将数据的key值作为数组下标,在数组的每个位置上连接一个单链表。

//开放寻址法
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 200003,null = 0x3f3f3f3f;
int h[N];

int find(int x)
{
	int k = (x%N+N)%N;
	while(h[k]!=null&&h[k]!=x)
	{
		k++;
		if(k==N) k=0;
	}
	return k;
}

int main()
{
	int n;
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin >> n;
	memset(h,0x3f,sizeof h);
	while(n--)
	{
		string op;
		int x;
		cin >> op >> x;
		int k = find(x);
		if(op == "i") h[k]=x;
		else
		{
			if(h[k]!=null) puts("Yes");
			else puts("No");
		}
	}
	return 0;
}

字符串哈希:

        字符串哈希是将字符串的前缀通过p进制转换成整型数据存储进哈希表中,可以快速解决字符串的一类问题,就是求一串字符串中的俩段子串相不相等。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010,P = 131;
char str[N];
unsigned long long h[N],p[N];

unsigned long long ha(int l,int r)
{
	return h[r] - h[l-1]*p[r-l+1];
}

int main()
{
	int n,m;
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin >> n >> m >> str;
	p[0] = 1;
	for(int i=1;i<=n;i++)
	{
		p[i] = p[i-1]*P;
		h[i] = h[i-1]*P+str[i];
	}
	
	while(m--)
	{
		int l1,l2,r1,r2;
		cin >> l1 >> r1 >> l2 >> r2;
		if(ha(l1,r1) == ha(l2,r2)) cout << "Yes";
		else cout << "No";
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值