简体   繁体   English

查找数字属于哪个间隔

[英]Find which interval a number belongs to

I have a large set of intervals (start, end) that are continguous and non overlapping. 我有大量连续且不重叠的间隔(开始,结束)。 Given a number, I want to find out which interval it belongs to. 给定一个数字,我想找出它属于哪个间隔。

I am currently coding up a binary search based solution - I wanted to know if this would be possible using standard library data structs such as TreeMap or a TreeSet. 我目前正在编写一个基于二进制搜索的解决方案-我想知道使用标准库数据结构(例如TreeMap或TreeSet)是否可以实现此目的。

If I understand your needs correctly, you have a List of ranges like (1,5), (6,10),(11,18) and so on. 如果我正确理解了您的需求,那么您将获得一个范围列表,例如(1,5),(6,10),(11,18)等。 When given an input like 4, you want to return the range which contains this input. 给定类似4的输入时,您想返回包含此输入的范围。

Here is a version in Scala: 这是Scala中的一个版本:

scala> val input = List((1,5), (6,10),(11,18))
input: List[(Int, Int)] = List((1,5), (6,10), (11,18))

scala> input.filter(elem => 4 <= elem._2 && 4 >= elem._1)
res1: List[(Int, Int)] = List((1,5))

You can expand on this by extracting this into a method and pass the input parameter. 您可以通过将其提取到方法中并传递输入参数来对此进行扩展。

You could replace the type of collection that you want depending on the use case. 您可以根据用例替换所需的集合类型。 Have a look here at the collections performance characteristics: 在这里查看集合的性能特征:

http://docs.scala-lang.org/overviews/collections/performance-characteristics.html http://docs.scala-lang.org/overviews/collections/performance-characteristics.html

If you want to use a TreeSet, you could do the following: 如果要使用TreeSet,可以执行以下操作:

scala> val in = TreeSet((1,5),(6,10),(11,15))
in: scala.collection.immutable.TreeSet[(Int, Int)] = TreeSet((1,5), (6,10))

scala> in.filter(elem => 4 <= elem._2 && 4 >= elem._1)
res2: scala.collection.immutable.TreeSet[(Int, Int)] = TreeSet((1,5))

Yes, it's possible to do using standard Java's or Scala's TreeMap (which is RB tree underneath). 是的,可以使用标准Java或Scala的TreeMap (位于其下方的RB树)进行操作。

Code: 码:

import scala.collection.immutable.TreeMap

val ranges = TreeMap((1, 5), (8, 10), (11, 18))

def contains(intervals: TreeMap[Int, Int])(el: Int) =
  intervals.to(el).lastOption.exists(_._2 >= el)

(-1 to 20).foreach { i =>
  println(s"$i ${contains(ranges)(i)}")
}

Prints: 印刷品:

-1 false
0 false
1 true
2 true
3 true
4 true
5 true
6 false
7 false
8 true
9 true
10 true
11 true
12 true
13 true
14 true
15 true
16 true
17 true
18 true
19 false
20 false

The idea is to use to method, that returns a projection of the map with keys smaller or equal to the given element. 想法是使用to方法,该方法返回键小于或等于给定元素的地图投影。 If your map contains the interval that intersects given point, then this interval will be the largest key in the projection. 如果您的地图包含与给定点相交的间隔,则此间隔将是投影中的最大关键点。 So the only thing left is to check that the value (right boundary) of that interval is larger than the element in question. 因此,剩下的唯一事情就是检查该间隔的值(右边界)是否大于所讨论的元素。

Both to and lastOption methods work in O(log n) for RB tree. tolastOption方法都在RB树的O(log n)工作。

This implementation assumes that ranges are inclusive, but it should be easy to modify this code for exclusive ranges. 此实现假定范围是包含范围的,但是为排他范围修改此代码应该很容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM