这是回复某一篇关于散列,完全散列的帖子写的代码。
再把问题描述一遍:
在两个很大的字符串数组中,求两个数组中共有的字符串
写一个o(m*n)的算法很容易
实际上引入hash,完全把复杂度降到o(m+n)
但是引入hash,需要注意hash冲突;当hashcode冲突时,需要在hash数组上纵向bucket;将重复hashcode存入到纵向bucket。
hash查询时,查询到某一bucket,再进行一次迭代查找hashcode
理想状态无冲突的复杂度为o(m+n)
假设平均冲突为常数k,则复杂度变为o(k(m+n))
实际情况下,当ary足够大,冲突会变得足够小,k可忽略不计。即o(k(m+n))=o(m+n)
下面是回复内容
mylazygirl 写道
leon_a 写道
算了,放代码,冲突是必须的,但当ary数组足够大,能有效避免冲突。
public class Main {
public static void main(String[] args) {
String[] strArr1 = { "xiaoxin", "niutou", "shanqiu", "luobo" };
String[] strArr2 = { "xiaoxin", "ggg", "shanqiu", "meile", "dddsf", "niutou" };
int max = strArr1.length > strArr2.length ? strArr1.length : strArr2.length;
int[] ary = new int[max*4];
for (int i = 0; i < strArr1.length; i++) {
int hash = hash(strArr1[i].hashCode());
int index = indexFor(hash,max*4);
ary[index] = 1;
}
for (int i = 0; i < strArr2.length; i++) {
int hash = hash(strArr2[i].hashCode());
int index = indexFor(hash,max*4);
if(ary[index] == 1){
System.out.println(strArr2[i]);
}
}
}
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length-1);
}
}
这位兄弟的代码我没看懂,用hash我倒是明白,但hash()方法就不知道是做什么的了,打印了一下值,发现有重复,于是将输入换一下
String[] strArr1 = { "xiaoxin", "niutou", "shanqiu"};
String[] strArr2 = { "ggg", "shanqiu", "meile", "dddsf", "niutou", "luobo"};
结果就错了,这个hash()方法莫不是随便做了做位操作而已,没什么意义?希望明白的人解答
那我就再放代码,无冲突版本
package test;
import java.util.Arrays;
public class Hash {
public static void main(String[] args) {
// String[] strArr1 = { "xiaoxin", "niutou", "shanqiu", "luobo" };
// String[] strArr2 = { "xiaoxin", "ggg", "shanqiu", "meile", "dddsf", "niutou" };
String[] strArr1 = { "xiaoxin", "niutou", "shanqiu" };
String[] strArr2 = { "ggg", "shanqiu", "meile", "dddsf", "niutou", "luobo" };
int max = strArr1.length > strArr2.length ? strArr1.length : strArr2.length;
int[][] ary = new int[max * 4][];
for (int i = 0; i < strArr1.length; i++) {
int hash = hash(strArr1[i].hashCode());
int index = indexFor(hash, max * 4);
if (ary[index] == null) {
ary[index] = new int[1];
} else {
ary[index] = Arrays.copyOf(ary[index], ary[index].length * 2);
}
for (int j = 0; j < ary[index].length; j++) {
if (ary[index][j] == 0) {
ary[index][j] = hash;
}
}
}
for (int i = 0; i < strArr2.length; i++) {
int hash = hash(strArr2[i].hashCode());
int index = indexFor(hash, max * 4);
if (ary[index] != null) {
for (int j = 0; j < ary[index].length; j++) {
if (ary[index][j] == hash) {
System.out.println(strArr2[i]);
}
}
}
}
}
static int hash(int h) {
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
return h & (length - 1);
}
}
分享到:
相关推荐
Facebook为每个应用分配一个唯一的秘钥散列,当你的应用尝试通过Facebook登录接口进行认证时,系统会将这个散列与Facebook服务器上注册的散列进行匹配。如果两者一致,认证过程才能继续,否则会被拒绝,确保了应用和...
散列查找技术是一种高效的数据检索方式,它通过一个特定的函数将给定的关键码转换成存储地址,即散列地址,从而直接访问数据,避免了传统的逐个比较查找。散列查找的核心在于散列函数的设计和冲突处理方法。 散列...
在本教程中,我们将深入探讨如何使用JavaScript来实现一个独特的“散列画廊”特效,这是一种将图片以独特散列模式展示的视觉效果。 散列画廊特效的核心在于对图像数据进行处理,将其转化为一种可以显示为像素化或...
线性开型寻址散列(Linear Probing Hashing)是一种常见的散列存储方法,它在处理冲突时采用线性的探测顺序。在这个数据结构中,我们首先计算元素的关键字(key)的散列值,然后在散列表中寻找对应的位置。如果该...
### 两种适用于中文信息搜集的URL散列函数的研究 #### 摘要 随着互联网信息量的爆炸式增长,搜索引擎面临着前所未有的挑战。为应对这一挑战,搜索引擎开始采用分布式技术来搜集信息,以提高信息处理的效率和能力。...
在Windows操作系统中,为了保护用户的登录口令不以明文形式存储,系统采用了散列函数进行加密处理。这里我们主要讨论的是LM(Lan Manager)和NTLM(NT LAN Manager)两种散列算法,它们在Windows XP及更早版本中被...
散列法中,散列函数构造方法多种多样,同时对于同一散列函数解决冲突的方法也可以不同。两者是影响查询算法性能的关键因素。对于几种典型的散列函数构造方法,做实验观察,不同的解决冲突方法对查询性能的影响。
《散列DMA设计的高速串口驱动技术》 在当今的工业控制领域,串口通信因其灵活性和广泛应用性,仍然是连接设备和交换数据的重要手段。随着技术的发展,串口通信速度的需求不断提升,传统的中断驱动方式在高波特率下...
散列算法,也被称为哈希算法,是一种在计算领域中广泛应用的技术,主要用于数据验证、存储索引和加密等场景。本资源包含六种常见的散列算法的C++源代码实现,包括CRC32、MD5、SHA-1、SHA-256、SHA-512以及Tiger-192...
《数据结构》实验报告——散列查找 散列查找是一种高效的数据检索技术,它通过将关键字映射到一个固定大小的数组(散列表)来实现快速查找。在本实验中,我们将深入理解并实践散列查找的基本原理和冲突解决策略。 ...
### Java中的散列算法——以SHA-1为例 在Java编程语言中,散列算法是一种非常重要的数据处理方法,主要用于确保数据的完整性和安全性。本文将深入探讨Java中的一种常见散列算法——SHA-1(Secure Hash Algorithm 1...
### SHA(安全散列算法) #### 一、概述 安全散列算法(Secure Hash Algorithm,简称SHA)是一种广泛应用于信息安全领域的数据加密算法。它最初由美国国家标准与技术局(National Institute of Standards and ...
根据给定的信息,我们可以分析出该段代码是关于散列算法的一个实现案例,主要通过C++语言编写(尽管代码实际采用的是C语言风格),用于构建一个基于散列表的马尔可夫链文本生成器。下面我们将详细解析这段代码中的...
在QT5中,QChart库为我们提供了一种强大的方式来创建各种图表,包括散列图(ScatterChart),这在数据分析和可视化中非常有用。散列图是一种将数据点以点的形式分布在二维平面上的图表,每个点的位置代表了两个变量...
### 认证及散列算法 #### 知识点概览 本文档主要围绕现代密码学中的消息认证与散列算法展开,详细介绍了几种常用的散列算法及其应用场景,并探讨了这些算法的安全性评估。 #### 散列算法简介 散列算法是一种将...
散列算法,全称为哈希算法,是一种在计算领域中广泛应用的数据摘要技术。SHA-1(Secure Hash Algorithm 1)是其中的一种,由美国国家安全局(NSA)设计,并于1995年发布,主要用于确保信息安全,比如数据完整性验证...
10散列法的实验研究,散列法中,散列函数构造方法多种多样,同时对于同一散列函数解决冲突的方法也可以不同。两者是影响查询算法性能的关键因素。
散列结构
二分法查找和散列查找是两种常用的查找算法,它们在不同的场景下有着各自的优势。 首先,我们来详细讨论二分法查找。二分法查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组...
其中,"完全散列"是一种高效的哈希表构造方法,旨在最大限度地减少哈希冲突,提高查找效率。在C++中实现完全散列,需要理解哈希函数的设计、装载因子、开放寻址法或链地址法等概念。 哈希表是一种数据结构,通过...