问题
I have an array of rectangles. Trying to find out a rect which contains given point. I can iterate this array and use CGRectContainsPoint to find the rect contains this point. Pseudo code is as follows
CGRect rectContainingPoint;
for (CGRect rect in arrayOfRects) {
if(CGRectContainsPoint(rect, point)) {
rectContainingPoint = rect;
break;
}
}
I feel this may not be elegant solution in terms of performance if my array is so large where I have to iterate large array. Can someone help me if there is any best solution or algorithm to find this in optimistic way.
回答1:
I feel this may not be elegant solution in terms of performance if my array is so large where I have to iterate large array. Can someone help me if there is any best solution or algorithm to find this in optimistic way.
First do you actually have a performance issue? Determine that before considering how to improve the algorithm. Once you're convinced something needs to be done then continue...
Your current solution is a linear search through a collection of rectangles, it is an O(N) solution. To improve on that you need a search method which reduces the number of tests you need to make, e.g. a binary search in an ordered collection has O(log N) behaviour which is a lot better.
To use an ordered collection you don't want to sort an unordered one for each search, full sorts are O(NlogN). Instead you need to think about keeping your collection sorted adding items so as to maintain the sort, performance of that can be O(log N) per insertion, same as for binary search.
Which just leaves the big question, can you devise a suitable ordering for your rectangles so they can be sorted? Ordering by the x-coordindate of the origin is possible, when testing for inclusion if the x-coordindate of the point is less than the x-coordinate of the origin then the point cannot be in any rectangle later in the ordering. You might wish to look into ordering based on both origin coordinates, etc.
TL;DR:
- Sort your list of rectangles and keep it sorted (O(log N) per insertion)
- Order your rectangles somehow, consider using the origin coordinate(s) for this
- Search for point's inclusion using something like binary search (O(log N))
That will probably make everything faster.
If you hit a problem once you've research sorting and searching and written some code ask a new question, showing your code, detailing your algorithm (in particular the ordering you picked), and describing the problem you hit. Somebody will undoubtedly help you out at that point.
HTH
回答2:
For large arrays you can use enumerated loop which will run on background thread without hampering your main thread.
来源:https://stackoverflow.com/questions/44531425/find-rectangle-contains-point-from-array-of-rectangles