zoukankan      html  css  js  c++  java
  • Hash(哈希/散列)表中冲突处理及命中计算

    前言

      本片博客主要讲的是哈希表中简单的冲突处理的方法,以及命中率计算。原理方面基本没有讲解,基本就讲个方法,主要用于知识记录以及帮助一些刷题玩家浏览。

      简而言之,不讲技术,只讲方法。

    引言

      写这篇博客的契机是在刷pat甲级题遇到了一道写哈希的题目,结果英文太次被欺负了。之后靠翻译读懂题目,结果被命中率给坑了,遥想起以前打比赛好像也被这个坑过,愤懑不平来写博。

      相关参考:https://blog.csdn.net/xyzbaihaiping/article/details/51607770

      相关题目:PAT (Advanced Level) Practice -- 1145 Hashing - Average Search Time (25 分)

    前缀知识

      hash:音译哈希,意译散列,用于在规定大小的表中,快速插入和查找数据。

      构造哈希表的几种方法:
        1.直接定址法(取关键字的某个线性函数为哈希地址)
        2.除留余数法(取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址)
        3.平方取中法(关键字平方后,取中间一段数字)
        4.折叠法
        5.随机数法
        6.数学分析法
      常用方法是直接定址法除留余数法
      一般做的题目都是喜欢自己写哈希的,简单而且好控制因为题目要求。直接定址题目一般会给你方法的,在此讲余数法。

    冲突处理

      冲突处理分成大类和小类,大类为开散列方法( open hashing,也称为拉链法,separate chaining )  闭散列方法( closed hashing,也称为开地址方法,open addressing )

      开散列我没写过,不提了,以后被坑可能会补。

      闭散列最常用的两个:线性探测(Linear probing)  二次探测(Quadratic probing)。(英文苦逼注意下,沙雕博主看不懂二次和探测的英文,结果卡题卡半天啊。看下混个眼熟)

      一、线性探测

        key = Hash(key) + 1

        key = Hash(key) + 2    以此类推。说明:hash(key)就是构造哈希的方法。

       如果是余数法,而且是来回探测的话:

        key =(Hash(key) + 1) % size

        key =(Hash(key) - 2 + size) % size     以此类推

       探测系数一直到size为止,那么也就是直到表满都放得下

      二、二次探测

        key = Hash(key) + 1*1

        key = Hash(key) + 2*2    以此类推

       如果是余数法,而且是来回探测的话:

        key =(Hash(key) + 1*1) % size

        key =(Hash(key) - 2*2 + size) % size     以此类推

       探测系数一直到size为止,如果路上查到的key都有数据的话,那么这个数据无法放入(题目特殊要求按题目定)

    命中计算

      其实没什么难度,主要是被坑了不爽无能狂怒rua

      按构表法和冲突处理法进行查找,没进行一次查找,查找次数+1,如果当前的查找那个位置是空的话,代表找不到,那么结束

      如果冲突系数一直到size还没找到,那么超过size的那次判断也算作一次查找  

    //msize是表的容量
    for(j=0;j<msize;j++) {
        cnt++;
            //没有找到或者找到了都算结束了
        if(a[(x%msize + j*j) % msize] == 0) break;
        if(a[(x%msize + j*j) % msize] == x) break;
    }
    //冲突处理完的这个判断,也算一次查找
    if(j == msize) cnt++;
    //除以总数,算平均值
    printf("%.1lf
    ",cnt*1.0/m);

      其实这个命中率并没有什么明确的规定,在此提出只是表示 “啊,这么狗的命中率也有啊” 的感想。刷题时(不管是比赛还是测试),都要随机应变,依靠样例去猜出题人的想法,今天可能出界+1,明天就可能没查到不算一次查询。

    后记

      感谢看到这么后面,这算是很胡闹的博文。比赛中技术知识只决定七成的结果,剩下的英语水平、码力和运气占的更多

      看到最近icpc徐州站和去年的青岛站有感而发

  • 相关阅读:
    界面控件DevExpress WPF入门 表达式编辑器功能
    Telerik UI for WPF全新版本——拥有Office2019高对比度主题
    DevExpress报表控件v21.2 全新的Visual Studio报表设计器
    报告生成器FastReport .NET入门指南 在Linux中启动应用程序
    文档控件DevExpress Office File API v21.2 自定义字体加载引擎
    UI组件库Kendo UI for Angular入门 如何开始使用图表功能
    WPF界面工具Telerik UI for WPF入门级教程 设置一个主题(二)
    DevExtreme初级入门教程(React篇) TypeScript支持
    报表开发利器FastReport .NET v2022.1 添加关键对象和属性
    python项目打包(一) setup.py、Python源代码项目结构
  • 原文地址:https://www.cnblogs.com/end-emptiness/p/9884279.html
Copyright © 2011-2022 走看看