鸽舍原理

// maxgap.cpp : 定义控制台应用程序的入口点。
//最大间隙问题:给定n个实数x1,x2,……xn。求这n个数在实数轴上相邻2个数之间的最大差值。
//假设对任何实数的下取整函数耗时O(1),设计求解最大间隙的线性时间算法。

#include "stdafx.h"
#include <iostream>

using namespace std;

/************************
功能:计算数组中最小元素的下标
输入:
输出:
************************/
template<class T>
int mini(int n,T* x)
{
 T temp=x[1];
 int k=1;
 for(int i=1;i<=n;i++)
  if(x[i]<temp)
  {
   temp=x[i];
   k=i;
  }
 return k;
}

/************************
功能:计算数组中最大元素的下标
输入:
输出:
************************/
template<class T>
int maxi(int n,T* x)
{
 T temp=x[1];
 int k=1;
 for(int i=1;i<=n;i++)
 {
  if (x[i]>temp)
  {
   temp=x[i];
   k=i;
  }
 }
 return k;
}

/************************
功能:计算最大间隙
输入:
输出:
************************/
double maxgap(int n,double* x)
{
 double minix=x[mini(n,x)],maxx=x[maxi(n,x)];//最大元素
 //用n-2个等间距点分割区间【minx,maxx】,产生n-1个桶,
 //每个桶i用high[i]和low[i]分别存储分配给桶i的数中的最大数
 //和最小数
 int* count=new int[n+1];//标记桶是否为空
 double* low=new double[n+1];
 double* high=new double[n+1];
 //桶初始化
 for(int i=1;i<=n-1;i++)
 {
  count[i]=0;
  low[i]=maxx;
  high[i]=minix;
 }
 //将n个数置于n-1个桶中
 for(int i=1;i<=n;i++)
 {
  int bucket=int((n-1)*(x[i]-minix)/(maxx-minix))+1;//哪个桶
  count[bucket]++;
  if(x[i]<low[bucket]) low[bucket]=x[i];
  if(x[i]>high[bucket]) high[bucket]=x[i];
 }
 //此时除了maxx和minix外的n-2个数被置于n-1个桶中。
 //由割舍原理知,至少有一个桶是空的。
 //这意味着最大间隙不会出现在同一个桶的两个数之间
 //对每一个桶做一次线性扫描即可找到最大间隙
 double temp=0,
   left=high[1];
 for(int i=2;i<=n-1;i++)
 {
  if(count[i])
  {
   double thisgap=low[i]-left;
   if(thisgap>temp) temp=thisgap;
   left=high[i];
  }
 }
 return temp;
}

int _tmain(int argc, _TCHAR* argv[])
{
 int n;
 //double* x;
 cout<<"Please input the amount of the array:"<<endl;
 cin>>n;
 double* x=new double[n+1];//@
 cout<<"The elements are:"<<endl;
 for(int i=1;i<=n;i++)
  cin>>x[i];
 cout<<"The maxgap is :"<<maxgap(n,x)<<endl;
 return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值