java-搜索已排序的矩形列表
我有一个矩形列表,以通常的方式创建:java-搜索已排序的矩形列表,java,algorithm,search,2d,sortedlist,Java,Algorithm,Search,2d,Sortedlist,我有一个矩形列表,以通常的方式创建: List<Rectangle> rects = new ArrayList<>(); 提供所需功能的朴素方法是在列表中循环并在每个矩形上调用contains方法,但这太慢了 当程序运行时,列表将被修改,但与需要搜索列表的速率相比,修改的速率微不足道,因此需要相对缓慢初始化的算法也可以 我看过Collections.binarySearch,但不知道如何使用它。我对Java没有太多的经验,所以如果有另一个集合可以类似于列表使用,但更适
List<Rectangle> rects = new ArrayList<>();
提供所需功能的朴素方法是在列表中循环并在每个矩形上调用contains方法,但这太慢了
当程序运行时,列表将被修改,但与需要搜索列表的速率相比,修改的速率微不足道,因此需要相对缓慢初始化的算法也可以
我看过Collections.binarySearch,但不知道如何使用它。我对Java没有太多的经验,所以如果有另一个集合可以类似于列表使用,但更适合我需要的搜索类型,那就太好了(我已经阅读了关于地图和集合之类的文档,但没有认识到任何优势) 您可以创建地图
映射是关联两个值的最佳方式。您可以将“x”值与其在列表中的第一个位置相关联。然后,您只需从列表中的第一个“x”位置循环到另一个“x”
如果你在地图上找不到“x”,那么你的列表上就没有好的矩形
通过这种方式,您不会浏览所有坏的“x”条目。您可以尝试查看流的性能。我不确定它是否足够快,但你可以测试一下
Rectangle rec = rects.stream().filter((r)->{
return r.contains(x, y);
}).findFirst().get();
使用<代码>映射在这里不合适,因为您没有创建键值对,流
也不适合此上下文
确保覆盖
矩形中的equals()
和hashCode()
,如下所述:您可以像这样使用并行流搜索列表
public Rectangle findContainingRectangle(final int x, final int y) {
List<Rectangle> rectangles = new ArrayList<>();
Rectangle rec = rectangles.parallelStream().filter((r)->{
if(r.getX()==x && r.getY()==y){
return true;
}
return false;
}).findFirst().get();
return rec;
}
public Rectangle find包含矩形(final int x,final int y){
列表矩形=新的ArrayList();
Rectangle=rectangles.parallelStream().filter((r)->{
if(r.getX()==x和&r.getY()==y){
返回true;
}
返回false;
}).findFirst().get();
返回记录;
}
在维护排序列表的同时,您可以在“X”坐标上使用二进制搜索来查找包含所需“X”的矩形的候选,然后在“Y”坐标上使用二进制搜索
您应该自己实现二进制搜索,我看不到可以使用Collections.binarySearch方法的方法
预期复杂度:O(logn)为n矩形的数量。
(因为您可能有重复的,所以会更详细一些)
然而,要做到这一点,您应该在添加其他实例的同时保持数组的排序,(在每次插入后排序)。只需多次运行二进制搜索,因为同一个x的概率很低,正如您所说,不会花费很多次,所以它仍然是logn
a) 运行二进制搜索
b) 删除找到的项目-并将索引保留在找到该项目的位置
c) 对剩余列表重复a)处的二进制搜索,直到返回null
d) 然后你有一个小的索引数组,你可以看到哪一个是最小的
e) 然后在指定位置重新插入移除的元素这似乎是一个解决方案:谢谢。我的例子有点“简单”,因为我只需要返回一个包含矩形的,但R树可能仍然是一个解决方案。
public Rectangle findContainingRectangle(final int x, final int y) {
List<Rectangle> rectangles = new ArrayList<>();
Rectangle rec = rectangles.parallelStream().filter((r)->{
if(r.getX()==x && r.getY()==y){
return true;
}
return false;
}).findFirst().get();
return rec;
}