尋找最近點對

具體分析見編程之美解法三,借鑑網上的代碼,但其有錯誤,再次修正。
代碼如下:

#include <stdio.h>  
#include <algorithm>  
#include <vector>  
#include <math.h>  
#include <stdio.h>  
#include <algorithm>  
#include <vector>  
#include <math.h>  


using namespace std;
class Point 
{  
public:
    Point(int x,int y):x_(x),y_(y){}
    Point():x_(0),y_(0){}
    static bool OrderByY(const Point &left,const Point &right)
    {
        return left.y_ < right.y_;
    }
    static bool OrderByX(const Point &left,const Point &right)
    {
        return left.x_ < right.x_;
    }
public:
    int x_;
    int y_;
};  
double Distance(const Point& left, const Point& right) 
{  
    return (sqrt(pow((double)(left.x_-right.x_),2) + pow((double)(left.y_-right.y_),2)));
}  
//採用分治歸併思想求多點之間的最小距離=min(left最小距離,right最小距離,left和right分別對應的最靠近的點的距離)
//left和right分別對應的最靠近的點的距離只可能出現在min_distance * (2*min_distance)的區域內,min_distance爲縱座標長度,
//2*min_distance橫座標長度,以min_distance爲原點。

double NearestPoints(const vector<Point>& points, int start, int end, Point *point1, Point *point2) 
{  
    if(end > start)
    {
        int middle = (start + end) / 2;
        Point point1_l,point2_l,point1_r,point2_r;
        double left_distance = NearestPoints(points,start,middle,&point1_l,&point2_l);//保留左邊最小值的座標對
        double right_distance = NearestPoints(points,middle+1,end,&point1_r,&point2_r);//保留右邊最小值的座標對
        double min_distance = left_distance > right_distance ? right_distance : left_distance;
        if(left_distance > right_distance)
        {
             *point1 = point1_r;
             *point2 = point2_r;
        }               //暫時保留的是除了中間帶狀區域的最小距離的座標對
        else
        {
             *point1 = point1_l;
             *point2 = point2_l;
        }
        vector<Point> left_part_points;
        for(int i = start;i <= middle;++i)
        {
            if(points[middle].x_-points[i].x_ <= min_distance)
                left_part_points.push_back(points[i]);
        }
        sort(left_part_points.begin(),left_part_points.end(),Point::OrderByY);
        vector<Point> right_part_points;
        for(int i = middle+1;i <= end;++i)
        {
            if(points[i].x_ - points[middle].x_ <= min_distance)
                right_part_points.push_back(points[i]);
        }
        sort(right_part_points.begin(),right_part_points.end(),Point::OrderByY);
        int distance_y = 0;
        double d = 0;
        for(int i = 0;i < left_part_points.size();++i)
        {
            for(int j = 0;j < right_part_points.size();++j)
            {
                 distance_y= left_part_points[i].y_ > right_part_points[j].y_ ? left_part_points[i].y_ - right_part_points[j].y_ 
                    : right_part_points[j].y_ - left_part_points[i].y_;//使兩個點的相對座標要在min_distance之內
                if(distance_y <= min_distance)
                {
                    d = Distance(left_part_points[i],right_part_points[j]);
                    if(d < min_distance)
                    {
                        min_distance = d;
                        *point1 = left_part_points[i];
                        *point2 = right_part_points[j];
                    }
                }
            }
        }
        return min_distance;
    }
    else
        return 0x7FFFFFFF;
}  



int main() 
{  
  std::vector<Point> points;  
  points.push_back(Point(2,3));  
  points.push_back(Point(1,4));  
  points.push_back(Point(3,0));  
  points.push_back(Point(1,5));  
  points.push_back(Point(0,5));  
  sort(points.begin(), points.end(), Point::OrderByX);  
  Point point1;  
  Point point2;  
  NearestPoints(points, 0, points.size() - 1, &point1, &point2);  
  printf("Point1: (%d, %d) <--> Point2: (%d, %d)\n", point1.x_, point1.y_, point2.x_, point2.y_);  
  system("pause");
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章