最近对问题(分治法)

来源:互联网 发布:笔记本如何卸载软件 编辑:程序博客网 时间:2024/05/22 10:22
#include "stdafx.h"#include <iostream>#include <math.h>using namespace std;struct point{double x, y;};double Distance(point a, point b);//声明函数,否则在c++中会出现“找不到标示符”的错误double ClosestDistance(point s[], int low, int high){int num,mid,index=0;double d,d1, d2, d3;point p[20];num = high - low;if (num == 1)//说明只有两个点,直接返回距离即是最近的return Distance(s[low], s[high]);else if (num == 2)//说明有三个点,求出两两点的最近值{d1 = Distance(s[low], s[low + 1]);d2 = Distance(s[low], s[high]);d3 = Distance(s[low+1], s[high]);d=(d1 < d2) ? ((d1<d3) ? d1 : d3) : ((d2>d3) ? d3 : d2);//比较三个值得大小,将最小的赋值给dreturn d;}else{mid = 0.5*(low + high);d1=ClosestDistance(s, low, mid);//在mid的左边的最近值d2 = ClosestDistance(s, mid+1, high);//在mid的左边的最近值,注意的是当mid的点在左边算上的时候在右边就不要在算了,不然就会导致结果错误if (d1 <=d2){d = d1;}else{d = d2;}//以下是解决求在跨区域中的两个点的最近值//首先可以根据已经求得的在两边的最近值排除一部分的点//即是,当两个点的X坐标的距离大于d的点将不再参与该轮的比较,因为显然它不可能是最近点对了for (int i = low; (i <=mid) && (s[mid].x-s[i].x < d); i++)//到mid的x坐标小于d的点的集合{p[index++] = s[i];}for (int i = mid+1; (i <= high) && (s[i].x - s[mid].x < d); i++){p[index++] = s[i];}//可以进行对y坐标的升序的排序,方便排除一些点for (int i = 0; i <= index; i++){for (int j = i + 1; j < index; j++){if (abs(s[i].y - s[j].y)>d)//两点的y坐标的差大于d,那就也不用比了break;else{d3 = Distance(s[i], s[j]);d = (d < d3) ? d : d3;}}}return d;//返回最近的值d}}double Distance(point a, point b){double d=sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));return d;}int main(int argc, _TCHAR* argv[]){double d;int i,n;point p[50];//将数组的大小设的大些,防止在下面发生溢出cout << "输入点的对数:n=" ;cin >> n;for (i = 0; i < n; i++)//将输入的值一次赋值到数组中{cout<< "x" << i << "=";cin >> p[i].x;cout << "y" << i << "=";cin >> p[i].y;cout << endl;}d=ClosestDistance(p, 0, n-1);cout << "最近距离是" << d << endl;}


0 0
原创粉丝点击