scala / java中的近似数字查找

时间:2017-04-24 22:53:39

标签: java scala data-structures

我希望有一个像对象一样的数字键,并返回大于或等于指定值的最小键的值。例如:

val m = NumericMap(1.0 -> "a", 1.5 -> "b", 1.8 -> "c")
m(0.5) // -> "a"
m(1.1) // -> "b"
m(1.6) // -> "c"

使用二叉树可以直接实现这样的东西,但我想知道这个数据结构是否有任何标准或库实现。

2 个答案:

答案 0 :(得分:7)

我建议您使用TreeMap<Double, String>

NavigableMap<Double,String> map = new TreeMap<>();
map.put(0.5, "a");
map.put(1.1, "b");
map.put(1.8, "c");

System.out.println(map.ceilingEntry(1.6).getValue());  // shows "c"

ceilingEntry方法返回其键是最小键的映射条目等于或大于指定的键。同样值得了解执行类似操作的floorEntrylowerEntryhigherEntry方法。

答案 1 :(得分:1)

如果您的地图在创建后没有发生变化(或者变化的次数比搜索次数少很多),那么最有效的实现就是两个数组。类似的事情(未经测试,可能在values.getOrElse(-i - 1, default)中有一个一个错误):

import java.util.Arrays

// assumes pairs are already sorted by key
class NumericMap[A](default: A, pairs: (Double, A)*) {
  private[this] val keys: Array[Double] = pairs.toArray.map(_._1)
  private[this] val values: Array[A] = pairs.toArray.map(_._2)

  def ceil(x: Double) = {
    val i = Arrays.binarySearch(keys, x)
    if (i >= 0)
      values(i)
    else {
      val insertionPoint = - i - 1
      if (insertionPoint < values.length)
        values(insertionPoint)
      else
        default
    }
  }

  def floor(x: Double) = // similar
}

Dawood ibn Kareem的答案的优点是你可以放心地认为它是正确的。