算法:使用关联键重叠1D段

时间:2017-01-13 21:48:50

标签: algorithm

如果每次都输入逻辑时间和唯一密钥,我该如何回馈识别每个密钥的逻辑时间的总序列(可能会被分解)。那个时候?

例如,逻辑时间为简单整数(可以递增或递减),以及可以比较的键:

type LogicalTime = Int
type Key = Char

-- Not necessarily ordered
skipList :: [(LogicalTime, LogicalTime, Key)]
skipList = 
    [ (100, 200, 'A')
    , (201, 300, 'B')
    , ( 20, 400, 'C')
    , (125, 150, 'D')
    , (151, 250, 'E')
    ]

expected :: [(LogicalTime, LogicalTime, [Key])]
expected =
    [ ( 20,  99, ['C'])
    , (100, 124, ['A','C'])
    , (125, 150, ['A','C','D'])
    , (151, 200, ['A','C','E'])
    , (201, 250, ['B','C','E'])
    , (251, 300, ['B','C'])
    , (301, 400, ['C'])
    ]

我可以天真地遍历找到的整个范围并循环遍历每个键条目来计算这一点,尽管我正在寻找更有效的方法。 (这不是语言特定的)

1 个答案:

答案 0 :(得分:1)

每个时间间隔(start, end, key)会触发两个事件:add(key,start)remove(key,end)。在迭代间隔列表时生成这些事件,然后按事件的时间(startend)对事件进行排序。然后,您可以浏览已排序的事件,生成在具有活动密钥的事件之前结束的间隔,并更新下一个间隔的密钥计数。

这是一些python代码:

events = []
for start,end,key in skipList:
  events.extend([(start-1, 1, key), (end, -1, key)])
events.sort()

startTime,_,firstKey = events.pop(0)
activeKeys = {firstKey:1}
expected = []
for time,delta,key in events:
  currentKeys = [k for k in activeKeys if activeKeys[k] > 0]
  currentKeys.sort()
  if startTime < time:
    expected.append((startTime+1, time, currentKeys))
  if not key in activeKeys:
    activeKeys[key] = 0
  activeKeys[key] += delta
  startTime = time

对于您的示例skipList,生成的输出为expected