首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 等级考试 > 复习指导 >

C++应用实例十九(1)

2009-01-10 
最近点对问题

    通过代码来学习实例,看下面的代码:
  //点结构
  typedef struct Pair
  {
  int x ;
  int y ;
  } Pair ;
  //最近点对结构
  typedef struct Closest_Pair
  {
  Pair pair_a ,pair_b ;
  double distance ;
  } Closest_Pair ;
  //点对结构
  typedef struct Points
  {
  Pair* p_pair ;
  int pair_nums ;//点对数目
  } Points
  //蛮力法:分别计算每一对点之间的距离,然后找距离最小的那一对
  bool Brute_Force(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  {
  for(int i=from ;i<=to ;++i)
  {
  for(int j=i+1;j<=to ;++j)
  {
  double next= Account_Distance_2(points.p_pair[i] ,points.p_pair[j]) ; if(closest_pair.distance > next )
  {
  closest_pair.pair_a = points.p_pair[i] ;
  closest_pair.pair_b = points.p_pair[j] ;
  closest_pair.distance = next ;
  }
  }
  }
  return true ;
  }
  //分治法:遵循分治方法,利用递归求出左子集和右子集的最近点对,然后再对两子集之间点对进一步分析比较,最后求出整个点集最近点对。
  void Divide_and_Conquer(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  {
  if( (tofrom+1) <4 )
  {
  Brute_Force(points ,closest_pair ,from ,to ) ;
  cout << "<4 " << closest_pair.distance << endl ;
  //system("pause") ;
  }
  else
  {
  int mid = (from+to)/2 ;
  int mid_value = points.p_pair[mid].x ;
  Divide_and_Conquer(points ,closest_pair ,from ,mid) ;
  Divide_and_Conquer(points ,closest_pair ,mid+1 ,to) ;
  Comp_CP(points ,closest_pair ,mid ,mid_value) ;
  }
  return ;
  }
  #include "Head.h"
  typedef int RedType ;
  typedef struct Pair
  {
  int x ;
  int y ;
  } Pair ;
  typedef struct Closest_Pair
  {
  Pair pair_a ,pair_b ;
  double distance ;
  } Closest_Pair ;
  typedef struct Points
  {
  Pair* p_pair ;
  int pair_nums ;//点对数目
  } Points ;
  Points points ;
  Closest_Pair closest_pair ;
  //int pair_nums ;
  double Account_Distance_2(const Pair& A ,const Pair& B )
  {
  return ( (A.xB.x)*(A.xB.x)+(A.yB.y)*(A.yB.y) ) ;
  }
  void Print_Points(ostream& outs ,const Points& points ,const Closest_Pair& closest_pair )
  {
  outs << "\n\n\n 随机产生点对如下:\n" ;
  for(int i=0 ;i<points.pair_nums ;++i)
  {
  outs << " (" << points.p_pair[i].x << " , " << points.p_pair[i].y << " ) " ;
  if((i+1)%5==0)
  {
  outs << endl ;
  }
  }
  outs << "\n\n 由以上点对可得最近点对为: ( "
  << closest_pair.pair_a.x << " , " << closest_pair.pair_a.y << " ) ,( "
  << closest_pair.pair_b.x << " , " << closest_pair.pair_b.y << " ) " ;
  outs << "\n 该点对距离为:" << closest_pair.distance << endl ;
  }
  bool Brute_Force(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  {
  for(int i=from ;i<=to ;++i)
  {
  for(int j=i+1;j<=to ;++j)
  {
  double next = Account_Distance_2(points.p_pair[i] ,points.p_pair[j]) ;//sqrt( )
  if(closest_pair.distance > next )
  {
  closest_pair.pair_a = points.p_pair[i] ;
  closest_pair.pair_b = points.p_pair[j] ;
  closest_pair.distance = next ;
  }
  }
  }
  return true ;
  }
  // 对顺序表L作归并排序

    void Merge(char sign ,Pair SR[] ,Pair TR[] ,long i ,long m ,long n)
  { // 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]
  //int j,k,l;
  for(int j=m+1,k=i;i<=m&&j<=n;++k) // 将SR中记录由小到大地并入TR
  {
  if(sign=='x')
  {
  if ( SR[i].x < SR[j].x )
  TR[k]=SR[i++];
  else
  TR[k]=SR[j++];
  }
  else
  {
  if ( SR[i].y < SR[j].y )
  TR[k]=SR[i++];
  else
  TR[k]=SR[j++];
  }
  }
  if(i<=m)
  {
  for(int l=0;l<=mi;l++)
  {
  TR[k+l]=SR[i+l]; // 将剩余的SR[i..m]复制到TR
  }
  }
  else
  {
  for(int l=0;l<=nj;l++)
  {
  TR[k+l]=SR[j+l]; // 将剩余的SR[j..n]复制到TR
  }
  }
  }
  void MSort(char sign ,Pair SR[] ,Pair TR1[] ,long s , long t)
  { // 将SR[s..t]归并排序为TR1[s..t].
  if(s==t)
  {
  TR1[s] = SR[s];
  }
  else
  {
  //int m ;
  int length = ts+1 ;//
  Pair* TR2 = new Pair[points.pair_nums];
  long m = (s+t)/2; // 将SR[s..t]平分为SR[s..m]和SR[m+1..t]
  MSort(sign ,SR,TR2,s,m) ; // 递归地将SR[s..m]归并为有序的TR2[s..m]
  MSort(sign ,SR,TR2,m+1,t) ; // 递归地将SR[m+1..t]归并为有序的TR2[m+1..t]
  Merge(sign ,TR2,TR1,s,m,t) ; // 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]
  delete[] TR2 ;
  }
  // cout << " Hello " ;
  }
  void Comp_CP(const Points& points ,Closest_Pair& closest_pair ,int mid ,int mid_value)
  {
  int i , j ;
  int distance = sqrt( closest_pair.distance ) ;
  i = mid ;
  while( i >= 0 && points.p_pair[i].x > (mid_valuedistance) )
  {
  j = mid ;
  while( points.p_pair[++j].x < (mid_value+distance) && j < points.pair_nums )
  {
  if( points.p_pair[j].y > (points.p_pair[i].y+distance) ||
  points.p_pair[j].y < (points.p_pair[i].ydistance) )
  //判断在y轴是否出界
  continue ;
  double next = Account_Distance_2( points.p_pair[i] ,points.p_pair[j]);//sqrt( )
  if(closest_pair.distance > next )
  {
  closest_pair.pair_a = points.p_pair[i] ;
  closest_pair.pair_b = points.p_pair[j] ;
  closest_pair.distance = next ;
  cout << "Comp_CP: " << closest_pair.distance << endl ;
  }
  }
  i ;
  }
  }
  void Divide_and_Conquer(const Points& points ,Closest_Pair& closest_pair ,int from ,int to)
  {
  if( (tofrom+1) <4 )
  {
  Brute_Force(points ,closest_pair ,from ,to ) ;
  cout << "<4 " << closest_pair.distance << endl ;
  //system("pause") ;
  }
  else
  {
  int mid = (from+to)/2 ;
  int mid_value = points.p_pair[mid].x ;
  Divide_and_Conquer(points ,closest_pair ,from ,mid) ;
  Divide_and_Conquer(points ,closest_pair ,mid+1 ,to) ;
  Comp_CP(points ,closest_pair ,mid ,mid_value) ;
  }
  return ;
  }
  void main()
  {
  time_t t;
  srand((unsigned) time(&t));
  char c ;
  do
  {
  system("cls") ;
  cout << "\n\n 请输入你要随机产生点对的对数: " ;
  cin >> points.pair_nums ;
  points.p_pair = new Pair[points.pair_nums] ;
  for(int i=0 ;i<points.pair_nums ;++i)
  {
  points.p_pair[i].x= rand()%101 ;
  points.p_pair[i].y= rand()%101 ;
  }

热点排行