重叠范围,变得独特

时间:2016-07-25 00:30:27

标签: range unique overlapping

我有一个范围列表,例如0-100。 我需要尽可能快地获得仅出现一次的唯一值。

例如范围:

0 - 10
5 - 20
30 - 40

0 - 10(+11)是唯一的,这些数字都没有出现在

之前

5 - 10不是唯一的,所以不要计算它们。

11 - 20(+10)是唯一的,30 - 40(+11)也是

这样它返回32。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

>>> a = range(11)
>>> b = range(5, 21)
>>> c = range(30, 41)
>>> set(i for i in a + b + c)
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40])
>>> len(_)
32

或更好:

>>> from itertools import chain
>>> a = xrange(11)
>>> b = xrange(5, 21)
>>> c = xrange(30, 41)
>>> set(chain(a, b, c))

在Python 3中:

>>> from itertools import chain
>>> a = range(11)
>>> b = range(5, 21)
>>> c = range(30, 41)
>>> set(chain(a, b, c))

希望它有所帮助!

答案 1 :(得分:1)

在您的示例中,范围按范围的下限按升序排序。我会假设这个解决方案始终如此。

基本上,我们的想法是迭代范围,每次都为计数变量添加唯一值。

要确定唯一值的起始位置,请比较上一个范围结束的位置与新范围开始的位置。

如果新范围的下限小于旧上限,即I.e。 0-10然后是5-20,根据您的示例,唯一值将从前一个上限+ 1开始(即,上限为10,唯一从11开始)。如果新的上限小于旧的上限,则没有要添加的新值(即0-10,然后是2-7)。

最后,如果新的下限大于旧上限(即5-20然后30-40),则所有新值都是唯一的。

伪代码:

var count = 0, lowerBound = 0, upperBound = 0;
foreach range in ranges:
   if range.lowerBound <= upperBound:
      if range.upperBound < upperBound:
         continue;
      else:
         lowerBound = upperBound + 1;
   else:
      lowerBound = range.lowerBound;
   upperBound = range.upperBound;
   count += upperBound - lowerBound + 1;