如何查找数字是否包含在java中的数字范围数组中

时间:2009-07-01 15:06:06

标签: java arrays search

我有一个java对象数组。

  • 每个对象存储两个定义数字范围的长整数。
  • 我已经保证对于范围内的所有对象,数字范围不会重叠。

我想快速找到数组中的特定对象,给定一个可能(或可能不)属于对象定义的数字范围之一的数字。

我希望使用Array.binarySearch执行此操作,但这看起来不合适。

有关最佳方法的任何想法吗?

3 个答案:

答案 0 :(得分:7)

使用TreeMap。关键是两个长距离边界中较低的一个;价值是对象。

private TreeMap<Long, T> map = new TreeMap<Long, T>();

void insertObject(T object) {
    map.put(object, object.getLowerRangeBoundary());
}

T getObjectByKeyInRange(Long query) {
    // Get the first Object in the tree that corresponds with the query
    Map.Entry<Long, T> e = map.floorEntry(query);

    // If there's no entry, then the query value is lower than all ranges in the tree
    if (e == null) {
        return null;
    }

    T target = e.getValue();
    // "target" is the only object that can contain the query value
    // If the query value is within the range of "target", then it is our object
    if (query < target.getUpperRangeBoundary()) {
        return target;
    }

    // Nobody has the query value in their range; return null
    return null;
}

答案 1 :(得分:4)

让数组中的项目实现Comparable接口,如果a.start&gt;允许项目a大于其他项目b弯曲。然后使用此比较对数组进行排序。

然后要查找数字x是否在数组中某个项目的范围内,请在数组中搜索第一个项目k并使用k.end&gt; = x,然后检查k.start&lt; = X。如果是这样,k就是范围。否则,x不在数组的任何范围内。

答案 2 :(得分:0)

您实际上可以非常有效地处理此问题(对于范围内的大量范围和数百万条查询)允许范围重叠。

伪代码:

让rangeMap成为TreeMap:

foreach(Range r in ranges)
    rangeMap[r.start].Increment();
    rangeMap[r.end].Decrement();

rangeMap.GreatestLowerBound(i)现在将返回给定整数i所属的范围数(即GreatestLowerBound是最大数字&lt; = i)。

如果你事先了解范围的数量,你可以做得更好......通过分配一个数组,用“deltaRange”填充它,然后“整合”得到一个显示累积的数组“范围“为每个数字x。