(演算法設計技巧與分析)CloseStpair
阿新 • • 發佈:2019-02-02
#include<iostream> #include<time.h> #include<math.h> using namespace std; class Point { public: int x; int y; void operator =(Point &p) {x=p.x;y=p.y;} void QuickSortx(Point a[],int low,int high);//快速排序 void QuickSorty(Point a[],int low,int high);//快速排序 double PointShortestDistance(Point x[],Point y[],int low,int high,Point &p1,Point &p2); friend ostream &operator<<(ostream &output,Point &cc); double distance(Point p1,Point p2) { int x=(p1.x-p2.x)*(p1.x-p2.x); int y=(p1.y-p2.y)*(p1.y-p2.y); return sqrt((double)(x+y)); } private: int splitx(Point a[],int low,int high); int splity(Point a[],int low,int high); }; int main() { Point p[10];//存放按x座標升序的座標 Point y[10];//存放按y座標升序的已經按x座標升序的座標 Point p1,p2;//存放最短距離的座標 int i; srand((unsigned int(time(NULL))));//匯入時間種子加每次執行結樣試下偽隨機數種子 for(i=0;i<10;i++) {p[i].x=rand()%100;p[i].y=rand()%100;cout<<p[i];} p[0].QuickSortx(p,0,9); for(i=0;i<10;i++) y[i]=p[i]; y[0].QuickSorty(y,0,9); cout<<p[0].PointShortestDistance(p,y,0,9,p1,p2)<<endl; cout<<p1<<p2; return 0; } int Point::splitx(Point a[],int low,int high) { int i=low;Point temp; for(int j=low+1;j<=high;j++) if(a[j].x<a[low].x) { i++; if(i!=j) { temp=a[i]; a[i]=a[j]; a[j]=temp; } } temp=a[i]; a[i]=a[low]; a[low]=temp; return i; } int Point::splity(Point a[],int low,int high) { int i=low;Point temp; for(int j=low+1;j<=high;j++) if(a[j].y<a[low].y) { i++; if(i!=j) { temp=a[i]; a[i]=a[j]; a[j]=temp; } } temp=a[i]; a[i]=a[low]; a[low]=temp; return i; } void Point::QuickSortx(Point a[],int low,int high) { if(low<high) { int w=splitx(a,low,high); QuickSortx(a,low,w-1); QuickSortx(a,w+1,high); } } void Point::QuickSorty(Point a[],int low,int high) { if(low<high) { int w=splity(a,low,high); QuickSorty(a,low,w-1); QuickSorty(a,w+1,high); } } ostream &operator<<(ostream &output,Point &cc) { output<<"("<<cc.x<<","<<cc.y<<")"<<endl; return output; } double Point:: PointShortestDistance(Point x[],Point y[],int low,int high,Point &p1,Point &p2) { int result=high-low; if(result<3)//只有三個點的時候直接求最短距離 { double d[3]; switch(result) { case 1:p1=x[low];p2=x[low];return x[low].distance(x[low],x[high]); case 2: d[0]=x[low].distance(x[low],x[low+1]); d[1]=x[low].distance(x[low+1],x[high]); d[2]=x[low].distance(x[low],x[high]); if(d[0]<d[1]) {p1=x[low];p2=x[low+1];} else {p1=x[low+1];p2=x[high];d[0]=d[1];} if(d[0]<d[2]) return d[0]; else {p1=x[low];p2=x[high];return d[2];} } } else { double dl,dr,d,d1; int i,j; Point t[10]; Point dp[4]; int number=0; int less; dl=x[low].PointShortestDistance(x,y,low,(low+high)/2,dp[0],dp[1]);//左半距離最短的座標 dr=x[low].PointShortestDistance(x,y,(low+high)/2+1,high,dp[2],dp[3]);//右半距離最短的座標 Point p=x[(low+high)/2]; if(dl<dr){d=dl;} else {d=dr;dp[0]=dp[2];dp[1]=dp[3];} d1=2*d; for(i=0;i<10;i++) if((y[i].x-p.x<d)&&(y[i].x-p.x>-d))//確定2d的範圍,number是t陣列的大小 { t[number]=y[i]; number++; } for(i=0;i<=number;i++) { less=(i+6)<(number+1)?(i+6):(number+1); for(j=i+1;j<less;j++) if(x[low].distance(t[i],t[j])<d1) { d1=x[low].distance(t[i],t[j]);dp[2]=t[i];dp[3]=t[j];} } if(d<d1) { p1=dp[0];p2=dp[1];} else {d=d1;p1=dp[2];p2=dp[3];} return d; } }