我试图从一系列范围中删除重叠值。
范围由如下字符串表示:
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
答案 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