我有一个java对象数组。
我想快速找到数组中的特定对象,给定一个可能(或可能不)属于对象定义的数字范围之一的数字。
我希望使用Array.binarySearch执行此操作,但这看起来不合适。
有关最佳方法的任何想法吗?
答案 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。