文章目录

  • 1 方法概括
  • 2 理论
    • 2.1 散列函数
    • 2.2 解决冲突
  • 3 具体方法
    • 3.1 数字存储
      • 3.1.1 直接定址(当N<10^5 , N为非负整数)
    • 3.2 字符串存储
      • 3.2.1 map
      • 3.2.2 进制转换
        • 3.2.2.1 string为大写字母
        • 3.2.2.2 string为字母
        • 3.2.2.3 string为字母+数字
        • 3.2.2.4 string为字母+数字(末尾)
        • 3.2.2.5 扩展(字符串较长)

1 方法概括

(1)字符串存储

  • map<int, string> 和 map<string int>
  • 进制转换 + 直接定址法

(2)数字存储

  • int arr[N] (直接定址法、除留余数法(有冲突))

2 理论

2.1 散列函数

  1. 直接定址
    恒等变换:H[key] = key(常用)
    线性变换:H[key] = a*key + b

  2. 除留余数
    H[key] = key % mod(常用)(H的表长 TSize>=mod:mod=TSize=素数)

  3. 平方取中

2.2 解决冲突

  1. 线性探查
    若对于key, H[key]已被占用
    则:一直 (H[key] +1)%SIZE(H[key]++,循环表长),直到找到空位

  2. 平方探查
    若对于key, H[key]已被占用
    则:k=1,2,…, 一直 ((H[key] ±k2k^2k2)%SIZE+SIZE)%SIZE(H[key]±k2k^2k2,循环表长,防止H[key]-k2k^2k2<0》),直到找到空位
    或只正向平方探查:k=1,2,…, 一直 (H[key] +k2k^2k2)%SIZE(H[key]+k2k^2k2,循环表长),直到找到空位

  3. 链地址 / 拉链
    Link[0]~Link[mod-1],mod可=TSize
    Link[i]:存一个单链表,H[key] = i 的所有结点(即有冲突的所有结点)

3 具体方法

3.1 数字存储

3.1.1 直接定址(当N<10^5 , N为非负整数)

例题:
已知N个正整数A[N],M个正整数B[M](N,M<=10510^5105)

  • 问1:将B[M]在A[N]中是否出现
    输入:
    A{2, 3, 6, 10}
    B{0, 3}
    输出:
    NO
    YES

  • 问2:将B[M]在A[N]中出现的次数
    输入:
    A{2,3,3,10}
    B{0, 3}
    输出:
    0
    2

(1)求是否查找成功,用bool
哈希:
bool hashTable[10000+10]; (默认=false)
遍历B[M]:hashTable[B[i]] = true;
遍历A[N]:if hashTable[A[i]] == true,则:找到,输出YES
O(M+N)

(2)求查中次数,用int

哈希:
int hashTable[10000+10]; (默认=0)
遍历B[M]:hashTable[B[i]] ++;
遍历A[N]:输出 hashTable[A[i]]

3.2 字符串存储

3.2.1 map

3.2.2 进制转换

3.2.2.1 string为大写字母

(1)代码

const int TSize = 26*26*26 + 10;
bool hashTable[TSize];// 字符串:3个字符(大写字母)
int hashFun(char str[]){int id=0;for(int i=0; i<strlen(str); i++){id = id*26 + (str[i] - 'A');}return id;
}

(2)小结

  • A~Z:26进制 转为 10进制
    id = …+ (str[1]-‘A’)* 26126^1261 + (str[0]-‘A’)* 26026^0260

3.2.2.2 string为字母

(1)代码

const int TSize = 52*52*52 + 10;
bool hashTable[TSize];// 字符串:3个字符(字母)
int hashFun(char str[]){int id=0;for(int i=0; i<strlen(str); i++){if(str[i]>='A' && str[i]<='Z'){id = id*52 + (str[i] - 'A');}else if(str[i]>='a' && str[i]<='z'){id = id*52 + (str[i] - 'a') + 26;}}return id;
}

(2)小结

  • A ~ Z,a ~ z:26+26=52进制 转为 10进制

3.2.2.3 string为字母+数字

(1)代码

const int TSize = 62*62*62 + 10;
bool hashTable[TSize];// 字符串:3个字符(字母+数字)
int hashFun(char str[]){int id=0;for(int i=0; i<strlen(str); i++){if(str[i]>='0' && str[i]<='9'){id = id*62 + (str[i] - '0');}else if(str[i]>='A' && str[i]<='Z'){id = id*62 + (str[i] - 'A') + 10;}else if(str[i]>='a' && str[i]<='z'){id = id*62 + (str[i] - 'a') + 10 + 26;}}return id;
}

(2)小结

  • 0~9,A ~ Z, a ~ z: 10+26+26=62进制 转为 10进制
  • -ASCII码:‘0’ < ‘A’ < ‘a’
    因此,进制转换只能此顺序

3.2.2.4 string为字母+数字(末尾)

const int TSize = 52*52*52*10 + 10;
bool hashTable[TSize];// 字符串:4个字符(3个字母+末尾一个数字)
int hashFun(char str[]){int id=0;for(int i=0; i<strlen(str)-1; i++){if(str[i]>='A' && str[i]<='Z'){id = id*52 + (str[i] - 'A');}else if(str[i]>='a' && str[i]<='z'){id = id*52 + (str[i] - 'a') + 26;}}id = id*10 + (str[strlen(str)-1] - '0');     //末尾1个数字return id;
}

(2)小结:

  • A ~ Z,a ~ z:52进制 转为 10进制,再直接 拼接 k个数字

3.2.2.5 扩展(字符串较长)

H[i] = H[i-1]*P+ index(str[i]) (P为进制)
当str都为大写字母 && len较小时
H[i] = H[i-1]*26 + str[i] - ‘A’

当str都为大写字母 && len较大时
const int MOD = 1e9 + 7;
const int P = 1e7+19;

long long H[i] = (H[i-1]*P + str[i] - ‘A’)%MOD

哈希存储:字符串存储、数字存储相关推荐

  1. Python 存储字符串时是如何节省空间的?

    本文为翻译文章,已得到 @rushter 的许可 原文链接:rushter.com/blog/python- 转载请注明出处 从 Python 3 开始,str 类型代表着 Unicode 字符串.取 ...

  2. 字符串队列c语言,C语言实现循环队列(队列可存储字符串)

    项目原因,需要写一个队列来存储串口实时输出的字符串.看了网上很多博文和一些数据结构的数据,给的例子都是实现对单个数字或者字符的队列操作,并没有实现在队列中存储字符串.这里分享一种可以实现的方法. 关于 ...

  3. (31)2021-01-20(JSON字符串和本地存储)

    JSON字符串和本地存储 一.json字符串 二.示例 1.对象或数组转JSON字符串 使用方法:JSON.stringify(数组或对象) 2.JSON字符串转对象或数组 使用方法:JSON.par ...

  4. iOS开发:沙盒机制以及利用沙盒存储字符串、数组、字典等数据

    iOS开发:沙盒机制以及利用沙盒存储字符串.数组.字典等数据 1.初识沙盒:(1).存储在内存中的数据,程序关闭,内存释放,数据就会丢失,这种数据是临时的.要想数据永久保存,将数据保存成文件,存储到程 ...

  5. python把数字逐一存入列表_python实现将range()函数生成的数字存储在一个列表中...

    说明 同学的代码中遇到一个数学公式牵扯到将生成指定的数字存储的一个列表中,那个熊孩子忽然懵逼的不会啦,,,给了博主一个表现的机会,,,哈哈哈好嘛,虽然很简单但还是记录一下吧,,,嘿嘿 一 代码 # c ...

  6. 字符串的存储方式以及静态存储区域、栈、堆

    下面两篇文章分析得比较详细.转自http://blog.csdn.net/yangdelong/archive/2010/04/03/5447362.aspx 文章来源 http://blog.csd ...

  7. C语言/关于字符串逆序存储

    关于字符串逆序存储问题,本文主要介绍了两种方法:1.递归 2.非递归 递归: 先利用my_strlen()函数求出所求字符串长度,字符串长度保存在变量len中(不含字符串'\0')(也可以直接使用库函 ...

  8. JS数字存储-指数位-尾数位-最大安全数字

    JS数字存储 存储标准 JavaScript中的数字的存储标准是IEEE754浮点数标准.代码中使用的无论是整数还是小数,都是同一种数据类型--64位双精度浮点型. 64位存储划分 64位分别是1位符 ...

  9. c语言单链表存储字符串,字符串的三种存储方式

    @[TOC] 在数据结构中,字符串要单独用一种存储结构来存储,称为串存储结构.这里的串指的就是字符串.无论学习哪种编程语言,操作最多的总是字符串.我们平常使用最多的存储结构无疑是利用定长数组存储.但是 ...

  10. c语言单链表存储字符串,串的块链存储结构(C语言)详解

    ,指的是使用 本节实现串的块链存储使用的是无头节点的单链表.当然根据实际需要,你也可以自行决定所用链表的结构(shujujiegou,该链表各个节点中可存储 1 个字符: 图 1 各节点仅存储 1 个 ...

最新文章

  1. 三星的 Logo 原来是这么来哦! | 每日趣闻
  2. BZOJ2822 [AHOI2012]树屋阶梯
  3. Wappo BFS求最短路+路径记录
  4. 关于mysql存储大数据的问题
  5. 跟着《架构探险》学轻量级微服务架构 (一)
  6. 转:小波函数介绍(wden)
  7. go 中gcc 编译问题(gcc.exe fatal error no input files compilation terminated)
  8. android progressdialog 倒计时,自定义progressdialog——带倒计时的progressbar效果
  9. 树分解 tree decomposition
  10. 【转】程序员:如何写出杀手级简历
  11. android画图 旋转 地球*月球,unity3d怎么实现地球太阳月球转动-unity3d实现地球太阳月球转动的方法 - 河东软件园...
  12. 打开计算机硬盘有声音,电脑硬盘有响声总吱吱响的解决方法
  13. 云大使的返利规则是什么
  14. Tromino谜题java_Tromino谜题
  15. wpf 响应键盘按键
  16. 基于Python/Capl脚本 对通信矩阵报文(Flexray/Can)的周期检测(二)
  17. GBase 8s灾备集群HAC (四) 异地灾备RSS
  18. C++ 字符串、string、char *、char[]、const char*的转换和区别
  19. 小白学习3D游戏建模从什么软件开始?人物角色建模怎么做?
  20. Python 多项式预测2019年天猫销售额

热门文章

  1. 使用Water-Scrum-Fall交付软件
  2. Android多点触摸 与 手势识别
  3. oracle:plsql学习总结(oracle database 10g sql 开发指南)
  4. php二维数组引用变量,PHP二维数组的引用赋值容易犯的错误
  5. hadoop api 复制文件_Hadoop核心架构是怎样的?
  6. 简述计算机的四代发展阶段 以及电子器件,2014计算机作业1答案
  7. 修改 font的文本信息_C#窗体,文本框如何实现类似html的输入提示信息
  8. 无边框Button(WPF)
  9. 【跃迁之路】【586天】程序员高效学习方法论探索系列(实验阶段343-2018.09.14)...
  10. 使用Jest对原生TypeScript项目进行UI测试