0
点赞
收藏
分享

微信扫一扫

蓝桥杯_数据结构_3 (hash表 - STL常用容器)

梦幻之云 2022-04-01 阅读 50

文章目录

hash表 O(1)

840. 模拟散列表




#include <iostream>
using namespace std;
#include<cstring>
const int N = 100003;   //取质数

int first_prim(int x) {//输入10^6^ 开始判断条件 
	for(int i = x; ; i++) {  //大于10^6^的第一个质数为1000003 作为mod值 
		bool flag = true;
		for(int j = 2; j * j<= i; j++) {
			if(i % j == 0) {
				flag = false;
				break;
			}
		}
		if(flag) {
			cout << i << endl;
			break;
		}

	}
	return 0;
}

//一个hash槽h[](存多条链),每个可以拉一条hash链 ,每一条链 e存对应位置元素值 , ne存下一个元素下标 , idx表示当前位置 
int h[N],e[N],ne[N],idx;   

void insert(int x) //把x映射到 0 ~ N 之间的一个数 
{	//如x为10^-9^ 就必须先mod再加N 
	int k = (x % N + N) % N;   //【 (如果余数负数 +N ) % N,余数就变成正数】,映射成正数 
	e[idx] = x;   //存值 (这里就想象单链表插入,把idx指向k位置的下一个位置,k的指针指向idx,当前位置idx++) 
	ne[idx] = h[k];	//idx->next = k->next = k+1 = h[k] (从0开始插入,k+1下标为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])  //沿着指针链找下一个点的下标 i = i->next (因为都在一条(初始值为-1)的数组上,最后到NULL即为-1)
		if(e[i] == x)
			return true;
			
	return false; 
}

int test_01()
{
	int n;
	scanf("%d",&n);
	
	memset(h,-1,sizeof(h));
	
	
	while(n--)
	{
		char op[2];
		int x;
		scanf("%s%d",op,&x);
		//*op 等效op[0] 
		if(*op == 'I') insert(x);
		else
		{
			if(find(x)) puts("Yes");
		 	else puts("No");  //puts在<iostream>中 
		}
	}
	
	return 0; 
} 

开放寻址法:




#include<cstring>
const int N = 200003, null = 0x3f3f3f3f;//每个数没有被使用的数都不在x范围内,作为结束条件 
int h[N];

int find(int x)
{
	int k = (x % N + N) % N ;   
	
	while(h[k] != null && h[k] != x)  //如果到最后都没有找到k ,返回k = 0 ,找到就返回k值 
	{
		k ++;
		if(k == N) k = 0;
	}
	return k;
} 
//first_prim(200000);大于此数的第一个质数 2000003  取长度N = 2000003 
int test_02()
{
	int n;
	scanf("%d",&n);
	
	memset(h,0x3f,sizeof(h)); //按字节赋值,每个字节0x3f ,所有int四个字节就变成0x3f3f3f3f 
	
	
	while(n--)
	{
		char op[2];
		int x;
		scanf("%s%d",op,&x);
		
		int k = find(x); //都有此句,写到外面 
		if(*op == 'I')//*op 等效op[0] 
		{
			//int k = find(x);       
			h[k] = x; // 先找的x的映射位置k ,再赋值 x  
		}
		else
		{
			//int k = find(x);
			if(h[k] != null) puts("Yes");
		 	else puts("No");  //puts在<iostream>中 
		}
	}
	
	return 0; 
} 

***字符串前缀hash法 (高效判断字符串-优于kmp)




typedef unsigned long long ULL;  // unsigned long long等效取模 mod 2^64^

const int N = 100010,P = 131; //或1331     统一用 p = 131 记住! 

int n,m;
char str[N];
ULL h[N],p[N];   //p数组存储p的多少次方的值 {p^1^,p^2^,p^3^,p^4^,p^5^};
//h[k]存前k个字符的hash值 
ULL get(int l,int r)  //计算区间hash值 
{
	return h[r] - h[l - 1] * p[r - l + 1];	//p^l-r+1^
}

int test_03()
{
	scanf("%d%d%s",&n,&m,str + 1);  //str从1开始存储 
	
	p[0] = 1;//P^0^ == 1
	for(int i = 1;i <= n;i++) //初始化!! 
	{
		p[i] = p[i - 1] * P; //注意 * 大写P  
		h[i] = h[i - 1] * P + str[i]; //保证str[i] != 0 就可以 
	 } 
	
	while(m--)
	{
		int l1,l2,r1,r2;
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);//顺序!! 
		
		if(get(l1,r1) == get(l2,r2)) puts("Yes");
		else puts("No");
		
	}
		
	return 0;
}

STL 常用容器




#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>

vector

string 字符串

pair 【自带了一个比较函数,比较first】

queue

优先队列 (大根堆)

stack

deque 双端队列 (功能全, 但缺点:速度慢很多)

set / multiset

bitset ,压位


#include<bits/stdc++.h>  //万能头文件   字节集bits/stdc++.h的头文件 
int test_04()
{
	vector<int> a;
	a.size();  //O(1)
	a.empty(); //返回数组是否为空 
	a.clear(); //并不是所有容器都有 
	
	for(int i = 0;i < 10;i++) a.push_back(i);
	
	for(int i = 0;i < a.size();i++) cout << a[i] << " ";
	cout << endl;
	
	for(vector<int>::iterator i = a.begin() ;i != a.end();i++) cout << *i << " ";
	cout << endl;
	
	//for(auto x : a ) cout << x << " ";    //5.11不允许 auto ??? 
	cout << endl;
	
	
	
	
	
	return 0;	
} 

int test_05()
{
	pair<int , string> p;
	
	p = make_pair(10,"wz");
	p = make_pair(20,"abc");
	
	//嵌套 三元组 
	pair<int, pair<int,string> > pp;
	
	
	//优先队列(默认大根堆) 
	priority_queue<int> heap;
	int x;cin >> x;
	heap.push(-x); //从大到小 【小根堆,输出时输出 (负负得正) -heap.pop() 即可】 
	cout << heap.top() << endl;
	
	
	priority_queue<int,vector<int> ,greater<int> > small_heap;
	
	
	//map的使用 
	map<string , int> a;
	
	a[];
	
	
}



int main() {
	
	test_05();
	
	return 0;

}
举报

相关推荐

0 条评论