【问题标题】:Keeping track of a list of items, even when items come and go: ruby跟踪项目列表,即使项目来来去去:红宝石
【发布时间】:2012-05-09 10:08:50
【问题描述】:

假设我有一个项目的哈希,并且我还保留了最大键的数量。

L = {1=>"item1", 2=>"item2", 3=>"item3"}, hi = 3

然后我删除了 1 个条目

L = {2=>"item2", 3=>"item3"}, hi = 3

现在我想添加另一个项目,但想重新使用已删除的密钥。
如何重新设计它以优化确定哪个是第一个可用密钥所需的时间?

我总是可以从 1 循环到 hi 并返回第一个可用的键,但即便如此,也许有一种快速的方法来编写它而不是手动调用循环并进行比较?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    嗯,有一种比使用显式循环更惯用的 Ruby 方式来编写它。像这样的:

    first_available = ( 1 .. hi+1 ).find { |k| !L.include? k }
    

    但是逻辑是一样的。除非您使用另一个变量来跟踪最小可用密钥,否则您无法真正避免类似的事情。

    【讨论】:

      【解决方案2】:

      没有办法避免一一对应,只能减少你必须经过的数字数量。

      例如,如果您将最小的可用数字保存在单独的变量中,则添加后,您所要做的就是检查从您刚刚使用的键开始的下一个最小值。

      就性能而言,除非您的散列将包含几百万个键,否则您不必担心必须按顺序查看每个键。即使哈希中有 100 万个键,您也可以在不到 1 秒的时间内连续找到最小值。

      【讨论】:

        【解决方案3】:

        例如,您可以对 Hash 进行子类化或修补,并跟踪最低可用数字(以及最高获取数字或您想要的任何其他数字)。类似于

        class MyHash < Hash
          # override
          def delete k
            @min_available ||= 0
            @min_available = k if k < @min_available
            # or you can have an array here to keep track of all freed slots
            #   if you want to sacrifice some memory for speed in this situation
        
            super k
          end
        
          def get_first_available
            # use @min_available to serve this request
          end
        end
        

        但话又说回来,如果您认为需要优化某些东西,最好有数据来支持该决定(提示:profile and measure)。

        【讨论】:

          猜你喜欢
          • 2010-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多