zoukankan      html  css  js  c++  java
  • 1078 Hashing (25 分)

    题意

    给出散列表长TSize和欲插入的元素,将这些元素按读入的顺序插入散列表中,其中散列函数为H(key) = key % TSize,解决冲突采用只往正向增加的二次探查法(即二次方探查法)。

    另外,如果题目给出的TSize不是素数,那么需要将TSize重新赋值为第一个比TSize大的素数再进行元素插入。

    样例解释

    TSize为4,所以需要先找到比4大的第一个素数(即5),于是TSize = 5。接着插入四个元素:
    key = 10,H(10) = 10%5 = 0,因此将10插入0号位。
    key = 6,H(6) = 6%5 = 1,因此将6插入1号位。
    key = 4,H(4) = 4%5 = 4,因此将4插入4号位。
    key = 15,H(15) = 15%5 = 0,发生冲突;采用二次方探查法,H(15+1x1)=1,发生冲突;H(15+2x2)=4,发生冲突;H(15+3x3)=4,发生冲突;H(15+4x4)= 1,发生冲...可以证明,后面找不到一个不冲突的时点。

    思路

    1. 首先,对于-一个输入的TSize,如果不是素数,则必须找到第一个比它大的素数。判断一个整数n是否是素数的方法:如果n不能被从2 ~Vn中的每-一个数整除,那么n是素数。
    2. 开一个bool型数组hashTable[],hashTable[key] == false 表示key号位未被使用。
      对每个插入的元素a,计算H(a)并判断对应位置是否被使用。
      • 如果未被使用,那么就找到可以插入的位置,并输出。
      • 如果已被使用, 根据二次方探查法,令步长step初值为1,然后令下一个检测值为(a+step * step) % TSize,判断该位置是否已被占用;如果已被占用,则令step++,再进行判断。step当自增达到TSize时如果还没有找到可用位置,则表明这个这个元素无法被插入(证明见注意点)。

    注意点

    1. Quadratic probing是指二次方探查法,即当H(a)发生冲突时,让a按(a+1^2,a-1^2,a+2^2,a-2^2,a+3^2,a-3^2...)的顺序调整a的值。本题中已经说明只要往正向解决冲突,因此需要按(a+1^2,a+2^2,a+2^3,...)的顺序调整a的值
    2. 冲突处理公式是(M=(a+step*step)%TSize),注意要模上TSize。
    3. 1号测试点“答案错误”的原因是:判断质数时把1也当成了质数。
    4. 证明如果step从0 ~ TSize-1进行枚举却仍然无法找到位置,那么对step大于等于TSize来说也不可能找到位置(即证明循环节为TSize)。
      这里只需要证明当step取TSize至2TSize-1也无法找到位置即可:
      (0 le x lt TSize),那么
      (a + (TSize + x) * (TSize + x)) % TSize
      =(a + TSize * TSize+ 2 * TSize * x + x * x) % TSize
      =(a + x * x) % TSize + TSize * TSize % TSize + 2 * TSize * x % TSize
      =(a + x * x) % TSize
      由于所有循环节为TSize,如果step从0 ~ TSize-1进行枚举却仍然无法找到位置,那么对step大于等于TSize来说也不可能找到位置。
    const int N=1e4+10;
    bool vis[N];
    int n,Tsize;
    
    int find(int key)
    {
        int k=key%Tsize;
    
        for(int i=0;i<Tsize;i++)
        {
            int t=(k+i*i)%Tsize;
            if(!vis[t]) return t;
        }
        return -1;
    }
    
    bool isprime(int x)
    {
        if(x<2) return false;
        for(int i=2;i*i<=x;i++)
            if(x % i == 0)
                return false;
        return true;
    }
    
    int main()
    {
        cin>>Tsize>>n;
        while(!isprime(Tsize)) Tsize++;
            
        for(int i=0;i<n;i++)
        {
            int x;
            cin>>x;
            int k=find(x);
            if(k != -1) 
            {
                vis[k]=true;
                if(i) cout<<' '<<k;
                else cout<<k;
            }
            else cout<<' '<<'-';
        }
        cout<<endl;
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    对公信贷系统与其他系统交互方式总结
    测试验收标准checklist
    测试风险汇报
    接口测试checklist
    52 | 深入浅出网站可扩展性架构设计
    51 | 深入浅出网站伸缩性架构设计
    html元素类型 块级元素、内联元素(又叫行内元素)和内联块级元素。(转载)
    IO流
    多线程
    Java网络编程
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14426939.html
Copyright © 2011-2022 走看看