`
leon_a
  • 浏览: 79031 次
  • 性别: Icon_minigender_1
  • 来自: 拜月神教
社区版块
存档分类
最新评论

散列,全散列

阅读更多
这是回复某一篇关于散列,完全散列的帖子写的代码。
再把问题描述一遍:
在两个很大的字符串数组中,求两个数组中共有的字符串

写一个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登录获取apk秘钥散列

    Facebook为每个应用分配一个唯一的秘钥散列,当你的应用尝试通过Facebook登录接口进行认证时,系统会将这个散列与Facebook服务器上注册的散列进行匹配。如果两者一致,认证过程才能继续,否则会被拒绝,确保了应用和...

    数据结构7.4散列查找技术

    散列查找技术是一种高效的数据检索方式,它通过一个特定的函数将给定的关键码转换成存储地址,即散列地址,从而直接访问数据,避免了传统的逐个比较查找。散列查找的核心在于散列函数的设计和冲突处理方法。 散列...

    JS实现图片散列特效

    在本教程中,我们将深入探讨如何使用JavaScript来实现一个独特的“散列画廊”特效,这是一种将图片以独特散列模式展示的视觉效果。 散列画廊特效的核心在于对图像数据进行处理,将其转化为一种可以显示为像素化或...

    线性开型寻址散列

    线性开型寻址散列(Linear Probing Hashing)是一种常见的散列存储方法,它在处理冲突时采用线性的探测顺序。在这个数据结构中,我们首先计算元素的关键字(key)的散列值,然后在散列表中寻找对应的位置。如果该...

    两种适用于中文信息搜集的URL散列函数的研究

    ### 两种适用于中文信息搜集的URL散列函数的研究 #### 摘要 随着互联网信息量的爆炸式增长,搜索引擎面临着前所未有的挑战。为应对这一挑战,搜索引擎开始采用分布式技术来搜集信息,以提高信息处理的效率和能力。...

    windows登录口令存储所使用的LM和NTLM散列函数

    在Windows操作系统中,为了保护用户的登录口令不以明文形式存储,系统采用了散列函数进行加密处理。这里我们主要讨论的是LM(Lan Manager)和NTLM(NT LAN Manager)两种散列算法,它们在Windows XP及更早版本中被...

    散列法的实验研究

    散列法中,散列函数构造方法多种多样,同时对于同一散列函数解决冲突的方法也可以不同。两者是影响查询算法性能的关键因素。对于几种典型的散列函数构造方法,做实验观察,不同的解决冲突方法对查询性能的影响。

    散列DMA设计的高速串口驱动技术

    《散列DMA设计的高速串口驱动技术》 在当今的工业控制领域,串口通信因其灵活性和广泛应用性,仍然是连接设备和交换数据的重要手段。随着技术的发展,串口通信速度的需求不断提升,传统的中断驱动方式在高波特率下...

    常用散列算法类源代码(6种)

    散列算法,也被称为哈希算法,是一种在计算领域中广泛应用的技术,主要用于数据验证、存储索引和加密等场景。本资源包含六种常见的散列算法的C++源代码实现,包括CRC32、MD5、SHA-1、SHA-256、SHA-512以及Tiger-192...

    数据结构c语言散列查找(实验报告)

    《数据结构》实验报告——散列查找 散列查找是一种高效的数据检索技术,它通过将关键字映射到一个固定大小的数组(散列表)来实现快速查找。在本实验中,我们将深入理解并实践散列查找的基本原理和冲突解决策略。 ...

    java的散列算法

    ### Java中的散列算法——以SHA-1为例 在Java编程语言中,散列算法是一种非常重要的数据处理方法,主要用于确保数据的完整性和安全性。本文将深入探讨Java中的一种常见散列算法——SHA-1(Secure Hash Algorithm 1...

    SHA(安全散列算法)

    ### SHA(安全散列算法) #### 一、概述 安全散列算法(Secure Hash Algorithm,简称SHA)是一种广泛应用于信息安全领域的数据加密算法。它最初由美国国家标准与技术局(National Institute of Standards and ...

    散列算法(C++)

    根据给定的信息,我们可以分析出该段代码是关于散列算法的一个实现案例,主要通过C++语言编写(尽管代码实际采用的是C语言风格),用于构建一个基于散列表的马尔可夫链文本生成器。下面我们将详细解析这段代码中的...

    qt5中自动导入文件生成散列图

    在QT5中,QChart库为我们提供了一种强大的方式来创建各种图表,包括散列图(ScatterChart),这在数据分析和可视化中非常有用。散列图是一种将数据点以点的形式分布在二维平面上的图表,每个点的位置代表了两个变量...

    认证及散列算法

    ### 认证及散列算法 #### 知识点概览 本文档主要围绕现代密码学中的消息认证与散列算法展开,详细介绍了几种常用的散列算法及其应用场景,并探讨了这些算法的安全性评估。 #### 散列算法简介 散列算法是一种将...

    散列算法SHA_1^_^

    散列算法,全称为哈希算法,是一种在计算领域中广泛应用的数据摘要技术。SHA-1(Secure Hash Algorithm 1)是其中的一种,由美国国家安全局(NSA)设计,并于1995年发布,主要用于确保信息安全,比如数据完整性验证...

    10散列法的实验研究

    10散列法的实验研究,散列法中,散列函数构造方法多种多样,同时对于同一散列函数解决冲突的方法也可以不同。两者是影响查询算法性能的关键因素。

    散列结构的画图解释图

    散列结构

    数据结构之二分法查找和散列查找实验

    二分法查找和散列查找是两种常用的查找算法,它们在不同的场景下有着各自的优势。 首先,我们来详细讨论二分法查找。二分法查找(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组...

    算法导论中完全散列的C++代码实现

    其中,"完全散列"是一种高效的哈希表构造方法,旨在最大限度地减少哈希冲突,提高查找效率。在C++中实现完全散列,需要理解哈希函数的设计、装载因子、开放寻址法或链地址法等概念。 哈希表是一种数据结构,通过...

Global site tag (gtag.js) - Google Analytics