哈希-普通哈希 字符串哈希 tired字典树

字典树:char str[i];
把字符串中的每个字母变成一个 haxi值
像树一样的存起来一连串的字符

一般哈希 : int x;
①拉链法:是把一个数字变成一个 hashe值 像邻接表一样挂起来
②开放寻址法:就是直接把数字转化为hashe值后放存放在一个简单的数组里

字符串哈希:char str[i];
一个字符串变成一个 haxi值 存放在一个数组里

字符串哈希

模板例题字符串哈希

下题解中的P一般取值131、13331
mod一般取一个素数,有时候错了就多改大几次,可正确的取值不止一个

#include<bits/stdc++.h> 
using namespace std;
#define N 10010
#define Mmax 1515 
const int mod = 9512687878, P = 131; 
typedef unsigned long long ull;
ull hz[N];
-------------------------------------------------
int hashe(char str[]) // 把一个字符串转化为哈希值 
{
	ull ans = 0;
	int len = strlen(str);
	for(int i=1; i<=len; i++)
	{
		ans = (ans*P + (ull)str[i]) % mod; 
		//把这个数字当作从p进制要转化为10进制 取模是数字太大了变小点
	}
	return ans;
}
--------------------------------------------------
int main()
{
	int n, ans; 
	cin >> n;
	for(int i=1; i<=n; i++)
	{
		char t[N];
		scanf("%s", t);
		int k = hashe(t);
		hz[i] = k;
	} 
	sort(hz+1, hz+n+1);
	for(int i=1; i<=n; i++)
	{
		if(hz[i] != hz[i+1]) ans++;
	}
	cout << ans;
	return 0;
}

例题:比较字符串的题型
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
typedef unsigned long long ULL;
const int N = 1e5+5,P = 131;//131 13331
ULL h[N],p[N];

// h[i]前i个字符的hash值
// 字符串变成一个p进制数字,体现了字符+顺序,需要确保不同的字符串对应不同的数字
// P = 131 或  13331 Q=2^64,在99%的情况下不会出现冲突
// 使用场景: 两个字符串的子串是否相同
----------------------------------------//模板1
ULL query(int l,int r)
{
    return h[r] - h[l-1]*p[r-l+1]; //把字符串对齐再相减 
}
--------------------------------------//模板1
int main()
{
    int n,m;  //字符串长8 询问3次 
    cin>>n>>m;	 
    string x;		//输入字符串  
    cin>>x;			
    
	//h[k]存储字符串前 k个字母的哈希值, p[k]存储 P^k mod 2^64
    //字符串从1开始编号,h[1]为前一个字符的哈希值
    
-----------------------------------------//模板2
    p[0] = 1; //p数组是用来对齐的辅助数组 
    h[0] = 0; //h[k]存储字符串前 k个字母的哈希值
    
    for(int i=0;i<n;i++)
		{
        p[i+1] = p[i]*P;            
        h[i+1] = h[i]*P + x[i];      //前缀和求整个字符串的哈希值
    }
---------------------------------------//模板2

    while(m--)
	{
        int l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;
        if(query(l1,r1) == query(l2,r2)) printf("Yes\n");
        else printf("No\n");

    }
    return 0;
}
//	为什么体现到代码里,那个get函数里不需要加 mod了呢
//	利用 unsigned long long 自然溢出,相当于自动对 2^64-1取模

上题解模板:

ULL query(int l,int r)
{
    return h[r] - h[l-1]*p[r-l+1]; //把字符串对齐再相减 
}

    p[0] = 1; //p数组是用来对齐的辅助数组 
    h[0] = 0; //h[k]存储字符串前 k个字母的哈希值
    
    for(int i=0;i<n;i++)
		{
        p[i+1] = p[i]*P;            
        h[i+1] = h[i]*P + x[i];      //前缀和求整个字符串的哈希值
    }

一般哈希

①拉链法
例题:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 3;
int idx = 0, e[N], h[N], ne[N];
------------------------------------------------------//模板
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;
	cin >> n;
	memset(h, -1, sizeof(h));//记得!!!! !!!!!!!!!
	while(n--)
	{
		char a;int b;
		cin >> a;
		cin >> b;

		if(a == 'I')
		{
			insert(b);
		}
		else
		{
			if(find(b)) printf("Yes\n");
			else printf("No\n");
		}
	}
	return 0;
}

开放寻址法 模板
它只能存下不一样的数 如果存像 2、2 就不行

   int h[N];

    // 如果x在哈希表中,返回x的下标;如果x不在哈希表中,返回x应该插入的位置
    int find(int x)
    {
        int t = (x % N + N) % N;
        while (h[t] != null && h[t] != x)  
        {
            t ++ ;
            if (t == N) t = 0;
        }
        return t;
    }

Tired字典树

Tired树(字典树)理解与例题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值