zoukankan      html  css  js  c++  java
  • 数据结构与算法-散列

    散列的引入

    考虑下面的问题

    给出N个正整数,再给出M个正整数,其中N,M<=105,问M中的每个数是否在N中出现过?

    最直观的解法:首先需要把N个数据存储起来,然后遍历M个数据,拿到每个M后,再遍历N,判断是否存在一个数与当前待判断数相等,时间复杂度为O(NM)。

    有一种空间换时间的解法:有一个大小为105的数组,数组中存储bool变量。读取N的时候,以N中的数作为数组下标,把数组下标对应位置的bool变量设置为true。再遍历M,把M中的数作为数组下标直接随机访问,如果为true,代表出现过。时间复杂度O(N+M)。

    c实现

    #include <stdio.h>
    
    bool hashtable[100000] = {false};
    
    void hashSearch(){
        int n = 0, m = 0;
        int tmp = 0;
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; ++i) {
            scanf("%d", &tmp);
            hashtable[tmp] = true;
        }
        for (int i = 0; i < m; ++i) {
            scanf("%d", &tmp);
            if (hashtable[tmp]) {
                printf("%d,YES
    ", tmp);
            } else {
                printf("%d,NO
    ", tmp);
            }
        }
    }
    
    int main() {
        hashSearch();
        return 0;
    }
    

    散列的定义

    上面的做法,通过把输入的数字作为数组下标来对数字的某些性质进行统计,后续再查询时,也是通过数组的随机访问直接定位,查找效率很高。

    但是现实中,首先数字可能很大,或者输入的是字符串,不能直接作为数组下标了,如何处理?

    散列 关注的就是这个转换的过程,进一步说,散列使元素通过一个函数转换为整数,并使得该整数尽可能唯一的代表这个元素。

    散列函数

    如果待散列的元素为整数,有以下常见的散列函数:

    • 直接定址法:采用 元素本身 (上面例题中的做法)或者元素的线性函数来定址,适合表元素数量较小的情况。
    • 数字分析法:分析待散列元素数字,通过抽取部分分布均匀的数字来作为散列地址,适合元素本身位数较大,并且数字分布有规律的情况。(比如手机号,身份证号等等)
    • 平方取中法:数字平方后,取中间的N位,适合 位数不大,不知道数据分布的情况
    • 叠加求和法:把一个多位数字按照位数 切割 分成多个数字,这些数字求和,取模。适合位数较大,不知道数据分布的情况
    • 除留余数法:取模得到散列地址,需要注意,除数尽量选择 小于等于表长的 素数

    如果带散列的元素为字符串,介绍一个散列函数,进制hash法

    假设字符中只包含A到Z这26个大写字母,A到Z可以视为0到25,那么这个字符串可以看作是一个26进制的数,将26进制转换为10进制,就得到了一个整数。

    从N进制转换为十进制的算法这里就不再细说,假设读者已经有了这个基础。

    上面的字符串hash,可以转换为下面的C实现代码:

    void hashFunc(char str[]) {
        int id = 0;
        for (int i = 0; i < strlen(str); ++i) {
            id = id * 26 + (str[i] - 'A');
        }
        printf("%s", id);
    }
    

    重点解释一下下面这行

     id = id * 26 + (str[i] - 'A');
    

    以一个字符串“ZZZ”为例,计算过程如下:

    可以看到,这个公式最终可以转换为N进制转换为10进制的公式。

  • 相关阅读:
    php mysqli 查询个门店数据(面向对象)
    php 上锁 概述
    php 小程序渠道推广,转发
    php 微信公众号获取用户信息
    php 小程序获取用户信息
    php 生成小程序二维码
    1、收集日志至指定主题
    hihoCoder 网络流四·最小路径覆盖
    hihocoder1393 网络流三·二分图多重匹配
    hihocoder1398 网络流五之最大权闭合子图
  • 原文地址:https://www.cnblogs.com/ging/p/13494855.html
Copyright © 2011-2022 走看看