如何将范围集合减少到最小范围集

时间:2015-12-24 05:58:15

标签: python string algorithm list range

我试图从一系列范围中删除重叠值。

范围由如下字符串表示:

powershell -noprofile -command "$files = Get-ChildItem $env:AppData\Skype -Recurse config.xml; foreach($file in $files) { (Get-Content $file.fullname) -replace '<(AdvertPlaceholder)>1</\1>', '<$1>0</$1>' | Set-Content $file.fullname }"

我希望将上述内容缩减为两个范围:499-505 100-115 80-119 113-140 500-550。这涵盖了所有值,没有重叠。

目前我有以下代码。

80-140 499-550

我将数组拆分为cr = "100-115 115-119 113-125 80-114 180-185 500-550 109-120 95-114 200-250".split(" ") ar = [] br = [] for i in cr: (left,right) = i.split("-") ar.append(left); br.append(right); inc = 0 for f in br: i = int(f) vac = [] jnc = 0 for g in ar: j = int(g) if(i >= j): vac.append(j) del br[jnc] jnc += jnc print vac inc += inc ,并将范围限制存储在-ar中。我成对迭代这些限制,如果br至少与i一样大,我想删除该元素。但该计划并不奏效。我希望它能产生这样的结果:j

2 个答案:

答案 0 :(得分:5)

快速而简短的解决方案,

from operator import itemgetter
from itertools import groupby

cr = "499-505 100-115 80-119 113-140 500-550".split(" ")
fullNumbers = []
for i in cr:
    a = int(i.split("-")[0])
    b = int(i.split("-")[1])
    fullNumbers+=range(a,b+1)

# Remove duplicates and sort it
fullNumbers = sorted(list(set(fullNumbers)))

# Taken From http://stackoverflow.com/questions/2154249
def convertToRanges(data):
    result = []
    for k, g in groupby(enumerate(data), lambda (i,x):i-x):
        group = map(itemgetter(1), g)
        result.append(str(group[0])+"-"+str(group[-1]))
    return result

print convertToRanges(fullNumbers)
#Output: ['80-140', '499-550']

对于程序中的给定集,输出为['80-125', '180-185', '200-250', '500-550'] 主要解决方案的可能缺点:这可能无法扩展!

答案 1 :(得分:3)

让我提供另一种解决方案,它不需要花费时间与范围大小的总和成线性比例。它的运行时间与范围的数量成线性比例。

def reduce(range_text):
    parts = range_text.split()
    if parts == []:
        return ''
    ranges = [ tuple(map(int, part.split('-'))) for part in parts ]
    ranges.sort()
    new_ranges = []
    left, right = ranges[0]
    for range in ranges[1:]:
        next_left, next_right = range
        if right + 1 < next_left:             # Is the next range to the right?
            new_ranges.append((left, right))  # Close the current range.
            left, right = range               # Start a new range.
        else:
            right = max(right, next_right)  # Extend the current range.
    new_ranges.append((left, right))  # Close the last range.
    return ' '.join([ '-'.join(map(str, range)) for range in new_ranges ]

此功能的工作原理是对范围进行排序,然后按顺序查看它们并合并相交的连续范围。

示例:

print(reduce('499-505 100-115 80-119 113-140 500-550'))
# => 80-140 499-550

print(reduce('100-115 115-119 113-125 80-114 180-185 500-550 109-120 95-114 200-250'))
# => 80-125 180-185 200-250 500-550