单射双向映射

时间:2018-01-29 01:15:23

标签: python dictionary hash perfect-hash injective-function

我经常处理injective的映射。在编程术语中,这可以表示为一个字典,其中所有值都是唯一的,当然还有所有键。

是否有一个内存高效的数据结构用于内射映射,具有您期望从词典中获得的所有时间复杂属性?

例如:

d = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

d.get(2) = 'b'  # this works with a normal dictionary
d.get('b', reverse=True) = 2  # but this is not possible

Two way/reverse map中的所有解决方案似乎都需要使用或组合两组映射,重点是让它更容易在双向映射上执行操作。对于那些整齐地记忆在案的小词典来说这很好,但对大词典来说并不好。

要求是应该没有额外的内存开销存储内射双向映射而不是仅存储单向映射的常规字典。

我理解字典使用哈希表,它使用关联数组数据类型。根据定义,关联数组实现密钥 - >具有唯一键的值映射。在理论上或实践中,是否有可能产生允许反向查找的智能内射映射?

如果

更新

在与@rpy讨论之后(参见下面的评论),任何有关如何使用完美的可逆散列函数设置类似python字典的对象的信息都会很有用。但是,当然,工作实施是理想的(我已经尝试过perfection)。

1 个答案:

答案 0 :(得分:1)

您的问题的最终答案是:否(对于任何有效的实施)

您提出了两个无法同时满足的要求:

  1. 不要使用额外的内存进行反向映射
  2. 不要为执行(反向)查找添加额外时间
  3. 为什么这两个限制禁止解决方案?

    映射是一对值(元组)。 最琐碎的实现是:

    按顺序搜索所有元组以进行匹配。

    对于前向和后向映射,这将具有相同的复杂性 但是,这显然违反了time-complexity properties you expect from dictionaries

    的期望

    如果您允许 O(n)复杂性,那么按顺序搜索元组集将为您提供正确的解决方案。

    通常,字典实现会尝试降低 O(1)或至少 O(n * log(n))的复杂性。这是通过引入额外的数据来加速查找(如哈希或树木)来实现的。不幸的是,这些辅助工具只能帮助一个方向,因为它们要么处理密钥(前向映射情况),要么处理值(反向映射情况)。

    因此,只要您需要保持查找复杂度(这也适用于修改复杂性,但通常字典是针对快速查找而定制的),您将需要添加数据以实现速度。

    整个问题归结为经典的记忆与速度的权衡。

    修改

    在一般实现中解决问题的方法(对于键和值允许获取数字表示的情况,如果那些不是整数),可能是:

    计算key的哈希值和值的哈希值,并在两个哈希值下注册元组。这样您就可以获取键或值并识别匹配的元组并返回正确的结果。当你允许返回匹配元组的集合时,这甚至适用于非内射的情况。

    这将需要更多空间(哈希条目的两倍),同时将查找复杂度保持在基于哈希的词典的典型值内。您可能需要密切关注哈希桶大小(冲突链的长度),尤其是当密钥和值的值集不是不相交时)