哈希表

大数据问题总结

ε祈祈猫儿з 提交于 2019-11-27 10:11:54
大数据与空间限制问题 statement:本篇文字是看书(最后有介绍)的总结,仅限于想法,没有代码实现。 1. 布隆过滤器:100亿个黑名单网页,使用额外空间不超过30GB,允许万分之一失误率。 常见于建立黑名单时过滤使用。使用多个(就k吧)相互独立的优秀的hash函数,创建一个m个bit的数组,先将数据进行k次hash,对结果%m,那么每个数据就可以在bit数组中置多个1(可能是k个也可能少于k个),这样在验证的时候,就可以在进行k次hash计算,然后判断bit数组中的对应位是否被置1,如果全部为1,可以认为是命中,在名单中,进行相应的处理。 2. 使用2GB内存找到20亿个整数中出现最多的数 20亿个整数,假定32位=4B,也要8GB内存才能一次性处理(还只是读入内存),现在个人机内存也才差不多8GB,当然服务器肯定是可以处理的,采用哈希表,key=4B,value=4B(大概需要16GB内存,然后读入数字,查找统计数和词频,最后遍历找到最大的)。然,现在要求2GB内存找出出现最多的数,只能先利用hash函数进行分块,具体分块的数目由数据量和内存大小来定。比如目前2GB内存,按照极端情况来算,所有数据都不同,或者只有一个出现两次,需要8B*20亿=16GB=2GB*8,可以分为8块,或者16块。按照16快的分法,每个小文件大小会来到1GB,2GB的内存当然可以处理

数据结构---哈希表

女生的网名这么多〃 提交于 2019-11-27 08:05:47
大部分来源小甲鱼数据结构视频 散列(哈希)技术是在记录的存储位置和它的关键字之间建立一个确定的关系(哈希函数),使得每个关键字key对应一个存储位置, 记录的存储位置=f(key)。 哈希函数是一种映射,设定灵活。 不同关键字可能会得到同一哈希地址即冲突。 哈希表概念: 根据设定的哈希函数H(key)和处理冲突的方法将一组关键字映像到一个有限的连续的存储空间(地址集)上,并以关键字在地址集中的“像”作为记录在表中的存储位置。 哈希表的查找步骤: 当存储记录时,通过散列函数计算出记录的散列地址 当查找记录时,我们通过同样的是散列函数计算记录的散列地址,并按此散列地址访问该记录 散列技术既是存储方法也是查找方法,且不需要迭代。 哈希函数的构造方法 : 构造散列函数的两个基本原则 1 计算简单 2 分布均匀 *** 1. 直接定址法 例一:有一个从1到100岁的人口数字统计表,其中,年龄作为关键字,哈希函数取关键字自身。 即:f(key) = key 例二:如果现在要统计的是1980年以后出生的人口数,那么我们对出生年份这个关键字可以变换为:用年份减去1980的值来作为地址。 即:f(key) = key – 1980 f(key)=a key+b 实际中使用不多 2 数字分析法 数字分析法通常适合处理关键字位数比较大的情况,例如我们现在要存储某家公司员工登记表,如果用手机号作为关键字

浅析java中的hashMap

回眸只為那壹抹淺笑 提交于 2019-11-27 07:51:59
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类。虽然 HashMap 和 HashSet 实现的接口规范不同,但它们底层的 Hash 存储机制完全一样,甚至 HashSet 本身就采用 HashMap 来实现的。 ===== 通过 HashMap、HashSet 的源代码分析其 Hash 存储机制 ===== 集合和引用 就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java 对象放入数组中,只是把对象的引用放入数组中,每个数组元素都是一个引用变量。 HashMap 的存储实现 当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例: HashMap<String , Double> map = new HashMap<String , Double>(); map.put("语文" , 80.0); map.put("语文" , 80.0); map.put("语文", 80.2); map.put("数学", 89.0); map.put("英语", 78.2); map.put(null , 78.5); map.put("null" , 78.6);

【JS数据结构】实现哈希函数

ε祈祈猫儿з 提交于 2019-11-27 07:43:08
一、优秀的哈希函数 在构造哈希表之前,我们需要一个哈希函数对数据进行哈希化。 那这个哈希函数怎么实现呢,根据前面一篇博客 【JS数据结构】认识哈希表 ,我们已经认识了什么是哈希表以及为什么需要设计一个哈希函数。 其实就是要达到两个目的: 能够快速地计算,快速地获取hashCode 让元素在哈希表中分布均匀。 1、幂的连乘 前面谈到的数据存储,一种方法是使用幂的连乘获取 hashCode give = 7 * 27^3 + 9 * 27^2 + 22 * 27 + 5 = 144941 采用这种方式,其实就是一个多项式,可化为: 这里相乘的次数为:n + (n - 1) + ... + 1 = n(n + 1) / 2次 相加的次数为: N次。 得到的时间复杂度为(N^2 + N)/ 2 即O(N^2) 2、霍纳法则(秦九韶算法) 霍纳法则是对多项式的优化,让相乘的次数变少,从而快速获取hashCode,化为以下形式: 以give为例 这里相乘的次数为:N次; 相加的次数为: N次。 得到的时间复杂度为(N + N) 即O(N) 所以使用霍纳法则可以大大地提高效率,减少计算时间。 3、如何做到均匀分布。 在设计哈希表时,我们已经有了两种处理映射到相同下标值的办法,即可以解决冲突,一种是链地址法,另一种是开放地址法。 不管是哪种方法,我们最好让数据在哈希表中 分布均匀 。

Rehashing Kernel Evaluation in High Dimensions阅读笔记

烈酒焚心 提交于 2019-11-27 07:19:59
%% %%研二了,开始磕盐了hh,方向是机器学习核方法,之前接触的不是很多,感觉理论性很强,硕士慎入坑啊。。。。 %%老师推荐阅读的第一篇文章就是《Rehashing Kernel Evaluation in High Dimensions》,连带参考文献已经读了不止三遍了,还是感觉有很多东西没有弄明白 %%想先写出来整理一下思绪,后面理解深入了会再补充改正 %% 核密度估计(KDE) 密度估计问题可以分为参数密度估计和非参数密度估计。 参数密度估计是先根据先验知识假设数据分布,通过训练样本学习分布的参数。 非参数密度估计不基于任何先验知识,通过将样本划分为不同的区域,估计每个区域的概率来近似数据的密度估计。 当数据集中数据的数量N很大时,我们近似将落入区域R的样本数量K占总样本数量的比例作为查询点的密度估计。 假设区域R足够小,那么内部每一点的概率都是一样的,单个点的概率乘区域体积就是区域概率P 结合上面两个式子,可以得到,查询点的概率密度: 核密度估计是直方图密度估计的一种改进:假设R为d维空间中一个以查询q为中心的超立方体,定义核函数表示一个样本是否落入超立方体中。核函数有远小近大的特点,因此和查询点离得近的点,核函数值大,接近1,此点落在查询点的近邻区域中,其密度值可以用来估计查询点的密度。 HBE HBE(Hashing-Based-Estimators): (1

java中四种引用类型

只谈情不闲聊 提交于 2019-11-27 07:00:01
java中四种引用类型    今天看代码,里面有一个类java.lang.ref.SoftReference把小弟弄神了,试想一下,接触java已经有3年了哇,连lang包下面的类都不了解,怎么混。后来在网上查资料,感觉收获颇多,现记录如下。 对象的强、软、弱和虚引用   在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及(reachable)状态,程序才能使用它。从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。    强引用(StrongReference)    强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。    ps:强引用其实也就是我们平时A a = new A()这个意思。 软引用(SoftReference)   软引用(soft reference)在强度上弱于强引用,通过类 SoftReference 来表示。它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是可以被暂时回收的

Redis Cluster集群的搭建与实践

ぃ、小莉子 提交于 2019-11-27 05:51:27
Redis Cluster集群 一、redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster 架构 图如下: 其结构特点: 1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。 2、节点的fail是通过集群中超过半数的节点检测失效时才生效。 3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。 4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。 5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。 1、redis cluster节点分配 现在我们是三个主节点分别是:A, B, C 三个节点,它们可以是一台机器上的三个端口,也可以是三台不同的服务器。那么,采用哈希槽 (hash slot

左神算法第五节课:认识哈希函数和哈希表,设计RandomPool结构,布隆过滤器,一致性哈希,岛问题,并查集结构

守給你的承諾、 提交于 2019-11-27 03:37:40
认识哈希函数和哈希表 MD5Hash值的返回范围:0~9+a~f,是16位,故范围是0~16^16(2^64)-1, 【Hash 函数】 ,又叫散列函数; Hash的性质: 1) 输入域无穷大; 2) 输出域相对固定较小; 3) 输入一样,输出一样; 4) 输入不一样,输出可能一样,也可能不一样; 5) 均匀分布在输出域中,如经典表中对17取模,使得每个桶内的长度基本一样;散列函数,如同香水在房间;Hash函数和输入的顺序无关; 第4条即是Hash碰撞的原因:多个输入对应同一个输出;这是必然会产生的,因为输入域无穷,输出域确实有穷的。 【Hash 表经典结构】 0~16 是17个桶,当不够用的时候,就会扩容。 【JVM 中的Hash 表】 设计RandomPool结构 【题目】 设计一种结构,在该结构中有如下三个功能: insert(key):将某个key加入到该结构,做到不重复加入。 delete(key):将原本在结构中的某个key移除。 getRandom():等概率随机返回结构中的任何一个key。 【要求】Insert、delete和getRandom方法的时间复杂度都是O(1); 分析:由于复杂度要求,使得不能遍历;使用两张表,map1和map2,并使用一个计数变量size,将map1存入为(str, size),map2为(size, str);增加同基本

字符串哈希

删除回忆录丶 提交于 2019-11-27 02:36:12
给定一个长度为n的字符串,再给定m个询问,每个询问包含四个整数l1,r1,l2,r2,请你判断[l1,r1]和[l2,r2]这两个区间所包含的字符串子串是否完全相同。 字符串中只包含大小写英文字母和数字。 输入格式 第一行包含整数n和m,表示字符串长度和询问次数。 第二行包含一个长度为n的字符串,字符串中只包含大小写英文字母和数字。 接下来m行,每行包含四个整数l1,r1,l2,r2,表示一次询问所涉及的两个区间。 注意,字符串的位置从1开始编号。 输出格式 对于每个询问输出一个结果,如果两个字符串子串完全相同则输出“Yes”,否则输出“No”。 每个结果占一行。 数据范围 1≤n,m≤105 输入样例: 8 3 aabbaabb 1 3 5 7 1 3 6 8 1 2 1 2 输出样例: Yes No Yes 字符串哈希一般用131或1331做进制 #include<bits/stdc++.h> #define ull unsigned long long using namespace std; const int maxn = 1e6+10; ull hsh[maxn],p[maxn]; char s[maxn]; ull gethash(int l,int r) { return hsh[r] - hsh[l - 1] * p[r - l + 1]; } int main(

C# string

爷,独闯天下 提交于 2019-11-27 01:26:27
1、string 是不可变的 每次对string的修改,都相当于重新创建一个string对象(驻留池中没有),返回引用。string是一个特殊的引用类型,具备值类型的特点。一般的引用类型,修改引用使其指向另一个对象,与修改引用对象的内容,是两个完全不同的概念。但是,对于string类型,对string内容的修改,会导致指向另一个string对象。因此,对于字符串频繁变化的情况,强烈建议使用StringBuilder 2、为什么把string设计成不可变的? 首先,string是程序中用到最多的类型,把string设计成不可变的,不会发生线程同步的问题。A线程访问string变量str,把str传递给str2,线程B对str2的修改,不会影响str。 其次,把string设计成不可变的,意味着,内容相同的引用可以指向同一块内存,节约内存。 3、怎么实现的? CLR初始化创建一个哈希表,在这个表中,key是字符串,value是是对字符串的引用。当一个新的string对象,初始化为文本常量,首先检查哈希表中是否包含该文本常量。如果包含,返回已经存在的引用。如果不包含,新建string对象,添加到哈希表,并返回引用。这样,就避免了重复分配内存。除非卸载AppDomain或者进程终止,否则内部哈希表的string对象不能被释放。 4、驻留池注意事项 只有文本常量的字符串才会进入驻留池