合并两个哈希的时间复杂度

时间:2015-11-02 23:33:00

标签: ruby hash merge

有人知道在ruby中使用(Merge)函数合并两个哈希的时间复杂度是什么?

在我看来,它将是O(n ^ 2),因为对于散列h1中的每个元素,应检查h2中的所有元素,如果两个散列中的两个元素具有相同的值,则键值为1他们应该改变。

我不确定我的假设是否正确。任何人都可以帮我找出合并哈希的时间复杂度吗?

4 个答案:

答案 0 :(得分:3)

您的假设是错误的,因为无需检查h1h2是否有任何重复的密钥。重复键的merge method状态默认为h2中的值。

至于真正的答案......你需要挖一点。

检查merge方法的来源会产生以下代码

static VALUE
rb_hash_merge(VALUE hash1, VALUE hash2)
{
    return rb_hash_update(rb_obj_dup(hash1), hash2);
}

所以继续。 Ruby source for rb_hash_update就是这个

rb_hash_update(VALUE hash1, VALUE hash2)
{
    rb_hash_modify(hash1);
    hash2 = to_hash(hash2);
    if (rb_block_given_p()) {
        rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
    }
    else {
        rb_hash_foreach(hash2, rb_hash_update_i, hash1);
    }
    return hash1;
}

最后the rb_hash_foreach source

rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
{
    struct hash_foreach_arg arg;

    if (!RHASH(hash)->ntbl)
        return;
    RHASH_ITER_LEV(hash)++;
    arg.hash = hash;
    arg.func = (rb_foreach_func *)func;
    arg.arg  = farg;
    rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
}

哈希值的一次迭代产生O(n)。

答案 1 :(得分:2)

获得O(n ^ 2)的理性并不合理。最多这将是一个O(n + m)操作,其中n == h1.keys.lengthm == h2.keys.length

以下是我如何编写合并操作:

  • O(n):创建一个内容为h1的新哈希:h_new = h1.dup
    • 假设我们需要将h1循环到dup(可能是非最佳解决方案)
  • O(m):迭代h2中的键:h2.keys.each { }
    • 循环中的Foreach键,插入h_new[key] = h2[key]

因此上述算法产生O(n + m)结果。

答案 2 :(得分:1)

Hash添加元素具有O(n)的渐近最坏情况步长复杂度,但O(1)的渐近最终情况下的最坏情况步长复杂度。合并与将第二个Hash的所有元素添加到第一个Hash相同,因此它具有O(n 2 )的渐近最坏情况步长复杂度,但是O(n)的渐近分摊最坏情况步长复杂度。

答案 3 :(得分:1)

  

对于散列h1中的每个元素,应检查h2中的所有元素   如果两个哈希中的两个元素具有相同的值,则为键值   其中一个应该改变。

实现这一目标的方法不那么复杂:

h1 = {
  a: 1,
  b: 2,
  c: 3,
}

h2 = {
  a: 'hello',
  d: 4,
}

results = {}

h1.each do |key, val| 
  results[key] = val
end

h2.each do |key, val| 
  results[key] = val
end

p results
p h1.merge h2

--output:--
{:a=>"hello", :b=>2, :c=>3, :d=>4}
{:a=>"hello", :b=>2, :c=>3, :d=>4}

所以O(n)