输入点的坐标,输出距离最小的点和距离
1。如果点的书目较小,则直接比较 2。如果数目较大,则分成两个部分A,B 3。求A,B中的最近点对 4。求A,B中各有一点的点对的距离最小者 5。在3,4中求出的三个点对中取最小的
代码: (error:4)
ClosestPoints.cpp ////////////////////////////////////////////////// // //输入点的坐标,输出距离最近的点对 // ////////////////////////////////////////////////// #include<math.h> #include "Merge.h" //#include "points.h" //数据类型1:按x排序的点 class Point1{ // friend float dist(const Point1&, const Point1&); // friend void close(Point1*, Point2*, Point2*, int, int, Point1&, Point1&, float&); // friend bool closest(Point1*, int, Point1&, Point1&, float&); // friend void main();
public: int operator <= (Point1 a)const{return (x<=a.x);}
//private: int ID; float x,y; }; //数据类型2:按y排序的点 class Point2{ // friend float dist(const Point2&, const Point2&); // friend void close(Point1*, Point2*, Point2*, int, int, Point1&, Point1&, float&); // friend bool closest(Point1*, int, Point1&, float&); // friend void main();
public: int operator <= (Point2 a)const{return (y<=a.y);}
//private: int p; // 数组X中相同的索引 float x,y; };
//计算两点距离 template<class T> inline float dist(const T& u, const T& v){ float dx = u.x-v.x; float dy = u.y-v.y; return sqrt(dx*dx + dy*dy); } void close(Point1 X[], Point2 Y[], Point2 Z[], int l, int r, Point1& a, Point1& b, float& d){ if(r-l ==1){ a = X[l]; b = X[r]; d = dist(X[l], X[r]); return; } if(r-l ==2){ float d1 = dist(X[l], X[l+1]); float d2 = dist(X[l+1], X[r]); float d3 = dist(X[l], X[r]);
if(d1 <=d2 && d1 <=d3){ a = X[l]; b = X[l+1]; d = d1; return; } if(d2<=d3){ a = X[l+1]; b = X[r]; d = d2; return; } else{ a = X[l]; b = X[r]; d = d3; } return; } //多于三个点,划分为两部分 int m = (l+r)/2; //分别在两个部分按y排序建表 int f=l, g= m+1; for(int i=l; i<=r; i++) if(Y.p>m) Z[g++]=Y; else Z[f++]=Y; //递归求解以上两部分 close(X, Z, Y, l, m, a, b, d); float dr; Point1 ar, br; close(X, Y, Z, m+1, r, ar, br, dr); if(dr<d){ a = ar; b = br; d = dr; } Merge(Z, Y, l, m, r);//恢复(重构)Y[]
//分开的两边的点的距离 与 之前的两部分中最短距离比较 int k = l; for(i = l; i<= r; i++) if(fabs(Y[m].x-Y.x)<d) Z[k++] = Y;//x距离小于d的点放入Z for(i=l; i<k; i++){ for(int j=i+1; j<k && Z[j].y-Z.y<d; j++){//比较y距离小于d的点 float dp = dist(Z, Z[j]); if(dp<d){ d = dp; a = X[Z.p]; b = X[Z[j].p]; } } } } bool closest(Point1 X[], int n, Point1& a, Point1& b,float& d){ //在n>=2个点中寻找最近的点对 //如果少于两个点,则返回false //否则, 在a和b中返回距离最近的两个点 if(n<2)return false;
//按x排序 MergeSort(X, n);
//创建一个按y排序的点数组 Point2 *Y = new Point2[n]; for(int i=0; i<n; i++){ Y.p = i; Y.x = X.x; Y.y = Y.y; } MergeSort(Y, n);
Point2* Z= new Point2[n];
//寻找最近点对 close(X, Y, Z, 0, n-1, a, b, d);
delete []Y; delete []Z; return true; } void main(){}
Merge.h #ifndef MERGE_H #define MERGE_H /* template<class T> void MergeSort(T a[], int n); template<class T> void MergePass(T x[], T y[], int s, int n); template<class T> void Merge(T c[], T d[], int i, int m, int r);*/
template <class T> void Merge(T c[], T d[], int l, int m, int r){ int i = l; int j = m+1; int k = l;
//只要存在i和j,则不断归并 while((i<=m)&&(j<=r)) if(c<=c[j]) d[k++] = c[i++]; else d[k++] = c[j++];
//考虑余下的部分 if(i>m) for(int q = j; q<=r; q++) d[k++] = c[q]; else for(int q = i; q<=m; q++) d[k++] = c[q]; } template <class T> void MergePass(T x[], T y[], int s, int n){ int i= 0; while(i<=n-2*s){ Merge(x, y, i, i+s-1, i+2*s-1); i= i+2*s; } if((i+s)<n)Merge(x, y, i, i+s-1, n-1); else for(int j=i; j<n-1; j++){ y[j]=x; } } template <class T> void MergeSort(T a[], int n){ T *b = new T[n]; int s=1; while(s<n){ MergePass(a, b, s, n); s+ = s; MergePass(b, a, s, n); s+ = s; } }
#endif
|