如何知道

时间:2016-10-24 07:54:53

标签: python

L = [('key1', 14), ('key2', 20), ('key3', 13), ('key4', 10), ('key5', 11)]

假设我得到了如上所述的list。每个元组的第二个元素在概念上表示块存储器的大小。这些块存储器是相邻的和顺序的。他们的关系可以表示为:

  

0 ____ 14 ____ 14 + 20 14 ____ + 20 + 13 14 ____ + 20 + 13 + 10 14 ____ + 20 + 13 + 10 + 11

现在用户会给我'绝对地址',我应该给他一个密钥来解密整个内存块。例如,如果他想访问地址'10',那么我应该为他返回key1。如果他想访问'15',那么我应该返回key2。

我的实施现在每次都要从头开始搜索。实际上,有许多内存块,用户希望一直访问。表现不好。

L = [('key1', 14), ('key2', 20), ('key3', 13), ('key4', 10), ('key5', 11)]
def get_key(address):
    c = 0
    offset = 0
    for i in L:
        if address < i[1] + offset:
            break
        c += 1
        offset += i[1]
    return c

print(get_key(15))

我如何改善表现?

  

数据结构没有   成为list(L)。但已知的事情应该是(1)块大小,   (2)密钥,(3)用户将访问“绝对地址”。

根据Burhan Khalid的指示,最终代码如下(另见How to find the cumulative sum of numbers in a list?):

from bisect import bisect
from itertools import accumulate

L = [('key1', 14), ('key2', 20), ('key3', 13), ('key4', 10), ('key5', 11)]
markers = [i[0] for i in L]
boundaries = list(accumulate([i[1] for i in L]))

##offsets = []
##offsets.append(boundaries[0])
##for offset in boundaries[1:]:
##   offsets.append(sum(offsets)+offset)

def buckets(value, boundaries, markers):
   i = bisect(boundaries, value)
   return markers[i]

print(buckets(67, boundaries, markers))

2 个答案:

答案 0 :(得分:5)

  1. 构建每个项目结束点的绝对地址列表。该列表的第二项显然保证升序。
  2. L2 = [('key1', 14), ('key2', 34), ('key3', 47), ('key4', 57), ('key5', 68)]

    1. 对上面列表中请求的绝对地址执行二进制搜索。
    2. 总时间复杂度应为O(n),空间复杂度为O(n),每个查询的时间为O(logn)

答案 1 :(得分:4)

您可以使用数组对分算法将请求的数量放入正确的偏移量。

documentation for the bisect module提供了以下示例,可以为此轻松修改:

>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
        i = bisect(breakpoints, score)
        return grades[i]

>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']

以下是您将如何使用它(未经测试):

markers = [i[0] for i in initial_list_of_tuples]
boundaries = [i[1] for i in initial_list_of_tuples]
offsets = []
offsets.append(boundaries[0])

for offset in boundaries[1:]:
   offsets.append(sum(offsets)+offset)

def buckets(value, boundaries, markers):
   i = bisect(boundaries, value)
   return markers[i]