ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Hash

2022-07-11 20:34:53  阅读:123  来源: 互联网

标签:10000 no int 链表 哈希 Hash


Hash(  哈希表    哈希查找  )

Hash表:

定义:

1.哈希表,也称散列表,是一种高效的数据结构。它的最大优点就是把数据存储和查找所消耗的时间

大大降低,几乎可以看成是 O(1)的,而代价是消耗比较多的内存。在当前竞赛可利用内存空间越

来越多、程序运行时间控制的越来越紧的情况下,“以空间换时间”的做法还是值得的。

tips:

1.哈希冲突,不能保证每个元素的关键字与函数值是一 一对应的,这样就产生了“冲突”。

Hash查找:

定义:

1.哈希是hash的音译,也称散列.

2. 哈希查找是一种按关键字编址的快速检索方法.

优势:

1.哈希查找是通过对记录的关键字值进行某种运算,直接求出记录的地址.

2. 快——关键字到地址直接转换,无需反复比较.

3. 核心不在于如何“比较”,而在于如何“计算”.

4. 最能体现计算机科学精髓的查找方法.

基本思想:

举个例子:

 假如说我们需要将1~13存放到拥有5个区间的哈希表里,那么如果画成图就应该是这样的.(用mod对数进行取余(5)进行存放).

 

 大概就是这样一个表,我们只需将1~13依次%填到相应位置就可以了。

但到了这里,同学们就会疑惑:

  1~5正常%就行了,但是6%5=1,而前面1%5也=1,但是一个区间不是只能存放一个数值吗?

  这就是“哈希冲突”.

这里许多人可能想到我们之前讲的——链表.

tips:

  我们可以在这里创建链表,随后依次往后填写就可以了.

 

 

 填好之后就是这样的.

hash查找代码实现:

构造:

1.哈希函数的构造 ·通常情况下,我们用除余法来构造哈希函数.

2.即选择一个适当的正整数b,用其对取模的余数作为哈希值。 ·其关键是b的选取,为了尽量避免.

冲突,一般选为能够存储下并且尽量大的素数(一般情况下我们根据空间取106左右的素数).

3.一般地说,如果b的约数越多,那么冲突.

例题:

模板题:

  哈希构造的链表中查询方式比较快。已知存在一个随机的数据表(表中数字均为正整数,

没有重复),数据个数n≤50000;现在给定一些整数,查询在表中是否存在。

输入格式:

   第一行,1个正整数n表示随机数字个数.

   第二行,n个随机数字.

   第三行,要查询的数字个数m(m≤10000) 第四行,要查询的m个数,空格隔开.

输入样例1:

  10

  23 45 8 9 100 12 5 2 88 21

  3

  34 21 7

输出样例1:

  no

  yes

  no

#include<bits/stdc++.h>
using namespace std;
const int b=10000,H=10000;//哈希取模%数字. 
int t,a[10000],ne[10000],aus[10000];
int pop,st[10000];
void init(){ //初始化哈希表. 
    t=0;
    while(pop) //我们用一个栈存储下出现过的哈希值.
       a[st[pop--]]=0;
}
void insert(int key){ //将一个数字插入哈希表. 
    int h=key%b; //除余法. 
    for(int e=a[h];e;e=ne[e])
       if(aus[e]==key) return; //诺链表中已存在当前数字则不再存. 
    if(!a[h]) st[++pop]=h; //把第1次出现的哈希值入栈.
    ne[++t]=a[h],a[h]=t; //建立链表.
    aus[t]=key; //建立链接表,存储值等于key的数字. 
}
 
bool query(int key){//数组模拟链表. 
    int h=key%b;
    for(int e=a[h];e;e=ne[e]) //查询链接.
       if(aus[e]==key) return true;
    return false;  
} 
 
int main(){ 
    int a[10000];
    init();//初始化. 
    int n,m;
    cin>>n;
    for(int i=1;i<=n;++i) {
        cin>>a[i];
        insert(a[i]);
    }
    cin>>m;
    int num;
    for(int i=1;i<=m;++i){
        cin>>num;
        if(query(num)) printf("yes\n");
        else printf("no\n");
    }
}

字符串hash:

给出一个长度为n的字符串,进行m次询问,每次询问字符串的序列[a,b]和序列[c,d]是否相等 .

输入格式:

第一行1个整数n,为字符串长度.

第二行1个长度为n的字符串.

第三行1个整数m 接下来m行,每行4个以空格分隔的整数a,b,c,d.

输出格式: 对于每个询问,输出一行答案 yes或no.

数据范围:1e4< n,m ≤1e6.

输入样例:

7

asasaaa

4

1 2 3 4

1 2 2 3

1 5 3 7

1 1 7 7

输出样例:

yes

no

no

yes

#include<iostream>
#include<algorithm>
#include<cstring>  
using namespace std;
const int N=1e3+5,MD=1000000007,D=27;
string s; 
int f[N],g[N]; // f 为前缀和,g[i] 为 D 的 i 次方
void prehash(int n){
    f[0] =0; // f 前缀和预处理
    for(int i=1;i<=n;i++) f[i]=(1LL*f[i-1]*D+s[i-1])%MD;
    g[0]=1;
    for(int i=1;i<=n;i++) g[i]=1LL*g[i-1]*D%MD;
}
int hash1(int l, int r){
    int a=f[r];
    int b=1LL*f[l-1]*g[r-l+1]%MD;
    return (a - b + MD) % MD; // 前缀和相减
}
int main(){   
    int n;
    cin>>n>>s;
    prehash(n); //预处理hash表 
    int m;
    cin>>m;
    int a,b,c,d;
    for(int i=1;i<=m;++i){//进行数字判断 
        cin>>a>>b>>c>>d; 
        if(hash1(a,b)==hash1(c,d))
            printf("yes\n");
        else
            printf("no\n");
    }
    return 0;    
}

再见!!!


 

Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash Hash 

 

标签:10000,no,int,链表,哈希,Hash
来源: https://www.cnblogs.com/boranhoushen/p/16467767.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有