zoukankan      html  css  js  c++  java
  • #哈希# ----- 哈希表初学

    哈希表

         哈希表是根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址。作为线性数据结构与表格和队列等相比,哈希表无疑是查找速度比较快的一种。

         对不同的关键字可能得到同一散列地址,即k1≠k2,而f(k1)=f(k2),这种现象称为碰撞(英语:Collision)。具有相同函数值的关键字对该散列函数来说称做同义词。综上所述,根据散列函数f(k)和处理碰撞的方法将一组关键字映射到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这种表便称为散列表,这一映射过程称为散列造表或散列,所得的存储位置称散列地址。

                         

    查找:

    1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值    了,就往下一个找,直到H(key)中没有值了,就放进去。
    2. 数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示       月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列     地址。
    3. 平方取中法:当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为:平方后中间几位和关键字中每一位都       相关,故不同关键字会以较高的概率产生不同的哈希地址。
    4. 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加可以有移位叠加和间界叠加两种方法。移位叠       加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。
    5. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
    6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之     后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
     
    输入n,输入数列An,再输入m个数查询是否在An内,在输出“YES”,否这输出“NO”。
     1 #include<cstdio>
     2 #define M 4194303 
     3 int n,m,ans,cnt;
     4 int s[50005];
     5 int hashline[M+1];
     6 int next[12600005];//
     7 int fline[12600005];//链上值 
     8 
     9 void insert (int x){//插入 
    10     int key=x%M;
    11     fline[++cnt]=x;
    12     next[cnt]=hashline[key];
    13     hashline[key]=cnt;
    14 }
    15 
    16 bool find (int c){//查询 
    17     int key=c%M;
    18     for(int i=hashline[key];i;i=next[i])
    19         if(c==fline[i])return true;
    20     return false;
    21 }
    22 
    23 int main(){
    24     scanf("%d%d",&n,&m);
    25     for(int i=1;i<=n;++i){
    26         scanf("%d",&s[i]);
    27         insert(s[i]);
    28     }
    29     for(int i=1;i<=n;++i){
    30         int c;
    31         scanf("%d",&c);
    32         if(find(c))printf("YES
    ");
    33         else printf("NO
    ");
    34     }
    35     return 0;
    36 }

    为减少冲撞,选好大质数M非常重要。

    M={1000000007,1998585857,4194303}

    好元素

    【问题描述】

    A一直认为,如果在一个由N个整数组成的数列{An}中,存在以下情况:

    Am+An+Ap = Ai (1 <= m, n, p < i <= N , m,n,p可以相同),那么Ai就是一个好元素。

    现在小A有一个数列,请你计算数列中好元素的数目

     

    【输入格式】

    第一行只有一个正整数N,意义如上。

    第二行包含N个整数,表示数列{An}。

    【输出格式】

    输出一个整数,表示这个数列中好元素的个数。

     

    【输入样例】

    Sample1

    2

    1 3

    Sample2

    6

    1 2 3 5 7 10

    Sample3

    3

    -1 2 0

     

    【输出样例】

    Sample1

    1

    Sample2

    4

    Sample3

    1

     

    【数据范围】

     对于10%的数据1<=N<=10

     对于40%的数据1<=N<=500 -10^5<=Ai<=10^5

     对于70%的数据1<=N<=5000 -10^6<=Ai<=10^6

     对于100%的数据1<=N<=5000 -10^9<=Ai<=10^9

     
     1 #include<cstdio>
     2 #define M 4194303
     3 int n,ans,cnt;
     4 int s[50005];
     5 int hashline[M+1];
     6 int next[12600005];
     7 int fline[12600005];
     8 
     9 void insert (int x){
    10     int key=x%M;
    11     fline[++cnt]=x;
    12     next[cnt]=hashline[key];
    13     hashline[key]=cnt;
    14 }
    15 
    16 bool find (int c){
    17     int key=c%M;
    18     for(int i=hashline[key];i;i=next[i])
    19         if(c==fline[i])return true;
    20     return false;
    21 }
    22 
    23 int pre(){
    24     for(int i=1;i<=n;++i){
    25         for(int j=1;j<i;++j)
    26             if(find(s[i]-s[j])){
    27                 ++ans;
    28                 break;
    29             }
    30         for(int j=1;j<=i;++j)insert(s[i]+s[j]);
    31     }
    32     return ans;
    33 }
    34 
    35 int main(){
    36     scanf("%d",&n);
    37     for(int i=1;i<=n;++i){
    38         scanf("%d",&s[i]);
    39         insert(s[i]);
    40     }
    41     ans=pre();
    42     printf("%d",ans);
    43     return 0;
    44 }
     
  • 相关阅读:
    HDU 5492 Find a path
    codeforce gym 100548H The Problem to Make You Happy
    Topcoder SRM 144 Lottery
    codeforce 165E Compatible Numbers
    codeforce gym 100307H Hack Protection
    区间DP总结
    UESTC 1321 柱爷的恋爱 (区间DP)
    HDU 4283 You Are the One (区间DP)
    HDU 2476 String painter (区间DP)
    UESTC 426 Food Delivery (区间DP)
  • 原文地址:https://www.cnblogs.com/wjting/p/6022445.html
Copyright © 2011-2022 走看看