【问题标题】:Mapping a range of integers to a single integer将整数范围映射到单个整数
【发布时间】:2014-06-21 12:56:18
【问题描述】:

我有一个函数,它接收一个整数作为输入,并根据这个输入的范围,为其分配一个难度值。我知道这可以使用 if else 循环来完成。我想知道是否有更有效/更清洁的方法。

我试图做这样的事情

TIME_RATING_KEY ={
    range(0,46):1,
    range(46,91):2,
    range(91,136):3,
    range(136,201):4,
    range(201,10800):5,
}

但是发现我们可以使用 range 作为 dict 中的键(对吗?)。那么有没有更好的方法来做到这一点?

【问题讨论】:

    标签: python django dictionary map


    【解决方案1】:

    您可以实现interval tree。这种数据结构能够返回与给定输入点相交的所有区间。 在您的情况下,间隔不重叠,因此它们总是会返回 1 个间隔。

    居中区间树在 O(log n + m) 时间运行,其中 m 是返回的区间数(在您的情况下为 1)。所以这会将复杂度从O(n) 降低到O(log n)

    这些区间树的思路如下:

    • 您考虑包含您拥有的所有区间的区间
    • 取该区间的中心,并将给定区间划分为在该点之前结束的区间、包含该点的区间和之后开始的区间。
    • 为在中心之前结束的区间和在中心之后开始的区间递归构造相同类型的树
    • 将包含中心点的区间保持在两个排序序列中。一个按起点排序,另一个按终点排序

    根据中心点向左或向右搜索。当您发现重叠时,您对要检查的排序序列使用二进制搜索(这不仅可以查找包含给定点的区间,还可以查找相交或包含给定区间的区间)。

    修改数据结构以返回特定值而不是找到的区间很简单。


    这就是说,从上下文来看,我认为您实际上不需要降低此查找的效率,您可能应该使用更简单且更易读的解决方案,因为它更易于维护并且出错的机会更少。

    不过,阅读有关 mroe 高效数据结构的信息在未来会变得有用。

    【讨论】:

      【解决方案2】:

      最简单的方法大概就是写一个简短的函数:

      def convert(n, difficulties=[0, 46, 91, 136, 201]):
          if n < difficulties[0]:
              raise ValueError
          for difficulty, end in enumerate(difficulties):
              if n < end:
                  return difficulty
          else:
              return len(difficulties)
      

      例子:

      >>> convert(32)
      1
      >>> convert(68)
      2
      >>> convert(150)
      4
      >>> convert(250)
      5
      

      附带说明:您可以在 Python 3.x 中使用 range 作为字典键,但不能直接在 2.x 中使用(因为 range 返回一个列表)。你可以这样做:

      TIME_RATING_KEY = {tuple(range(0, 46)): 1, ...}
      

      但是这不会有太大帮助!

      【讨论】:

      • 谢谢。这非常有帮助
      猜你喜欢
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-29
      • 2023-03-03
      • 1970-01-01
      • 2017-06-13
      相关资源
      最近更新 更多