Ruby on rails 检测Ruby中的重叠范围

Ruby on rails 检测Ruby中的重叠范围,ruby-on-rails,ruby,arrays,Ruby On Rails,Ruby,Arrays,我有一系列的范围: [[39600..82800], [39600..70200],[70200..80480]] 我需要确定是否存在重叠。在ruby中,什么是一种简单的方法 在上述情况下,输出应该是“重叠的”。这是一个非常有趣的难题,特别是如果您关心性能的话 如果范围只有两个,那么这是一个相当简单的算法,扩展部分也介绍了这个算法 def ranges_overlap?(r1, r2) r1.cover?(r2.first) || r2.cover?(r1.first) end 如果您想

我有一系列的范围:

[[39600..82800], [39600..70200],[70200..80480]]
我需要确定是否存在重叠。在ruby中,什么是一种简单的方法


在上述情况下,输出应该是“重叠的”。

这是一个非常有趣的难题,特别是如果您关心性能的话

如果范围只有两个,那么这是一个相当简单的算法,扩展部分也介绍了这个算法

def ranges_overlap?(r1, r2)
  r1.cover?(r2.first) || r2.cover?(r1.first)
end
如果您想比较多个范围,这是一个相当有趣的算法练习

您可以在所有范围内循环,但需要将每个范围与所有其他可能性进行比较,但这是一个具有指数成本的算法

更有效的解决方案是执行二进制搜索,或者使用数据结构(如树)来计算重叠

此问题也将在页面中进行解释。计算重叠基本上包括查找树的交点。

考虑以下情况:

class Range
  include Comparable

  def <=>(other)
    self.begin <=> other.begin
  end

  def self.overlap?(*ranges)
    edges = ranges.sort.flat_map { |range| [range.begin, range.end] }
    edges != edges.sort.uniq
  end
end

Range.overlap?(2..12, 6..36, 42..96) # => true
类范围
包括可比
def(其他)
开始,开始
结束
def自重叠?(*范围)
边=ranges.sort.flat_映射{| range |[range.begin,range.end]}
边缘!=edges.sort.uniq
结束
结束
范围重叠?(2..12,6..36,42..96)#=>正确
注释

  • 这可以包含任意数量的范围
  • 请看一看,并通过一些测试来使用代码
  • 该代码创建一个平面数组,其中包含每个范围的起点和终点
  • 如果不重叠,此数组将保留顺序。(用一些例子形象化比用文字解释原因更容易,试试看)

  • 为了简单易懂,我建议采用以下方法:

    def overlaps?(ranges)
      ranges.each_with_index do |range, index|
        (index..ranges.size).each do |i|
          nextRange = ranges[i] unless index == i
          if nextRange and  range.to_a & nextRange.to_a 
            puts "#{range} overlaps with #{nextRange}"
          end
        end
      end
    end
    
    
    r = [(39600..82800), (39600..70200),(70200..80480)]
    overlaps?(r)
    
    以及输出:

    ruby ranges.rb 
    39600..82800 overlaps with 39600..70200
    39600..82800 overlaps with 70200..80480
    39600..70200 overlaps with 70200..80480
    

    这不是一种方法吗

    def any_overlapping_ranges(array_of_ranges)
       array_of_ranges.sort_by(&:first).each_cons(2).any?{|x,y|x.last>y.first}
    end
    
    p any_overlapping_ranges([50..100, 1..51,200..220]) #=> True
    

    在ActiveSupport中,存在范围#重叠?:从技术上讲,你有一系列的范围。这是一个很好的谜题,但这不是一个谜题网站-请发布你解决它的尝试,不要要求现成的解决方案。做
    1..3
    3..5
    “重叠”?你好,@broisasse。你已经擅离职守了。Rails有
    Range#重叠?
    ,所以在使用Rails=)时对
    Range
    类进行猴子补丁时要小心。我认为这将是二次成本,而不是指数成本,O(c^n)。如果保证n很小,那么就可以了。