1. 程式人生 > >(演算法設計技巧與分析)CloseStpair

(演算法設計技巧與分析)CloseStpair

#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;
	}
}