栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Swift中为Int数组(自定义字符串结构)实现哈希协议

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Swift中为Int数组(自定义字符串结构)实现哈希协议

更新资料

马丁·R 写道:

Swift 4.1开始 , 如果所有成员都符合Equatable /
Hashable(SE0185),则编译器可以自动进行合成

Equatable
Hashable
实现类型一致性。从 Swift 4.2开始
,Swift标准库(SE-0206)中内置了一个高质量的哈希组合器。

因此,不再需要定义自己的哈希函数,只需声明一致性即可:

struct ScalarString: Hashable, ... {    private var scalarArray: [UInt32] = []    // ... }

因此,下面的答案需要重写(再次)。 在此之前,请从上面的链接中参考Martin R的答案。


旧答案:

将我的原始答案提交给代码审查后,该答案已被完全重写。

如何实现到哈希协议

该哈希的协议允许您使用您的自定义类或结构作为字典键。为了实施此协议,您需要

  1. 实现Equatable协议(Hashable继承自Equatable)
  2. 返回计算结果
    hashValue

这些要点来自文档中给出的公理:

x == y
暗示
x.hashValue == y.hashValue

其中

x
y
是某种类型的值。

实施平等协议

为了实现Equatable协议,您可以定义类型如何使用

==
(等效)运算符。在您的示例中,等效性可以这样确定:

func ==(left: ScalarString, right: ScalarString) -> Bool {    return left.scalarArray == right.scalarArray}

==
函数是全局函数,因此它超出了您的类或结构。

返回计算结果
hashValue

您的自定义类或结构还必须具有一个计算

hashValue
变量。一个好的哈希算法将提供广泛的哈希值。但是,应注意,您不必保证哈希值都是唯一的。当两个不同的值具有相同的哈希值时,这称为哈希冲突。发生冲突时,这需要一些额外的工作(这就是为什么需要良好的分布)的原因,但是某些冲突是可以预期的。据我了解,该
==
功能可以完成额外的工作。(

有多种计算哈希值的方法。例如,您可以做一些简单的事情,就像返回数组中的元素数一样。

var hashValue: Int {    return self.scalarArray.count}

每当两个数组具有相同数量的元素但值不同时,就会产生哈希冲突。

NSArray
显然使用这种方法。

DJB哈希函数

DJB哈希函数是与字符串一起使用的常见哈希函数。这是我将要使用的那个,但是在这里请查看其他一些。

@MartinR提供的 Swift实现如下:

var hashValue: Int {    return self.scalarArray.reduce(5381) {        ($0 << 5) &+ $0 &+ Int($1)    }}

这是我原始实现的改进版本,但让我也包括了较旧的扩展格式,对于不熟悉的人来说,它可能更易读

reduce
。我认为这是等效的:

var hashValue: Int {    // DJB Hash Function    var hash = 5381    for(var i = 0; i < self.scalarArray.count; i++)    {        hash = ((hash << 5) &+ hash) &+ Int(self.scalarArray[i])    }    return hash}

&+
运营商允许
Int
溢出和长串重新开始。

大图景

我们已经研究了各个部分,但现在让我展示与哈希协议相关的整个示例代码。

ScalarString
是问题中的自定义类型。当然,这对于不同的人来说是不同的。

// Include the Hashable keyword after the class/struct namestruct ScalarString: Hashable {    private var scalarArray: [UInt32] = []    // required var for the Hashable protocol    var hashValue: Int {        // DJB hash function        return self.scalarArray.reduce(5381) { ($0 << 5) &+ $0 &+ Int($1)        }    }}// required function for the Equatable protocol, which Hashable inheirits fromfunc ==(left: ScalarString, right: ScalarString) -> Bool {    return left.scalarArray == right.scalarArray}

其他有用的阅读

  • 哪种哈希算法最适合唯一性和速度?
  • 溢出运算符

学分

非常感谢CodeReview中的MartinR。我的改写主要是基于他的回答。如果您觉得这有帮助,请给他点赞。

更新资料

Swift现在是开源的,因此可以从源代码中了解如何

hashValue
实现。它似乎比我在这里给出的答案更复杂,并且我还没有花时间对它进行全面分析。自己动手做。
String



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/377898.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号