How to divide a set of overlapping ranges into non-overlapping ranges?

前端 未结 5 1150
伪装坚强ぢ
伪装坚强ぢ 2021-02-13 23:22

Let\'s say you have a set of ranges:

  • 0 - 100: \'a\'
  • 0 - 75: \'b\'
  • 95 - 150: \'c\'
  • 120 - 130: \'d\'

Obviously, these range

5条回答
  •  终归单人心
    2021-02-13 23:52

    I'd say create a list of the endpoints and sort it, also index the list of ranges by starting and ending points. Then iterate through the list of sorted endpoints, and for each one, check the ranges to see which ones are starting/stopping at that point.

    This is probably better represented in code... if your ranges are represented by tuples:

    ranges = [(0,100,'a'),(0,75,'b'),(95,150,'c'),(120,130,'d')]
    endpoints = sorted(list(set([r[0] for r in ranges] + [r[1] for r in ranges])))
    start = {}
    end = {}
    for e in endpoints:
        start[e] = set()
        end[e] = set()
    for r in ranges:
        start[r[0]].add(r[2])
        end[r[1]].add(r[2])
    current_ranges = set()
    for e1, e2 in zip(endpoints[:-1], endpoints[1:]):
        current_ranges.difference_update(end[e1])
        current_ranges.update(start[e1])
        print '%d - %d: %s' % (e1, e2, ','.join(current_ranges))
    

    Although looking at this in retrospect, I'd be surprised if there wasn't a more efficient (or at least cleaner-looking) way to do it.

提交回复
热议问题