鸽舍原理求最大间隙

鸽舍原理:也称"抽屉原理"或利克雷原则,它是一个重要而又基本的数学原理,应用它可以解决各种有趣的问题,并且常常能够得到令人惊奇的结果,许多看起来相当复杂,甚至无从下手的问题,利用它能很容易得到解决。
原理1:把n+1个元素分成n类,不管怎么分,则一定有一类中有2个或2个以上的元素。
原理2:把多于m×n个物体放到n个抽屉里,那么一定有一个抽屉里有m+1个或者m+1个以 上的物体。
原理2-1:把m个元素任意放入n(n<=m)个元素,则一定有一个集合至少有k个元素。 其中 k= [m/n]([]表示向上取整)。
(抽屉原理的一般含义为:"如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有 n+1或多于n+1个元素放到n个集合中去,其中必定至少有一个集合里至少有两个元素。" ) 
                                                                                   ----- http://baike.baidu.com/view/9738418.htm
 
鸽舍原理求最大间隙:
问题描术:
最大间隙问题:给定n个实数x1,x2,……,xn,求这n个数在实轴上相邻2个数之间的最大差值。假设对任何实数的下取整方法耗时为O(1),设计解最大间隙问题的线性时间算法。
编程任务:
对于给定的n个实数x1,x2,……,xn。编程计算它们的最大间隙。
输入:
5
2.3  3.1  7.5  1.5  6.3
输出:
3.2
 
代码如下:
 
#include
#include
#include
#include
#include
#include    //for memset()
#include     //for floor()
 
#define _Print_ 0
 
using namespace std;
 
//打开文件,将数据保存到vector类型的vec中
template
int readfile(string filename, vector &vec)
{
 ifstream ifile(filename.c_str(), ios_base::binary | ios_base::in);
 if (!ifile)
 {
  cerr << "cannot open file!\n";
  exit(1);
 }
 string str("");
 getline(ifile, str);//第一行数据总个数,也可以直接统计vec长度
 str = "";
 while (getline(ifile, str))
 {
  size_t pos = 0;
  size_t pos2 = 0;
  while (pos2 <= str.size())
  {
   pos = str.find(' ', pos2);
   if (pos != -1)
   {
    vec.push_back(atof(str.substr(pos2, pos - pos2).c_str()));
    pos2 = ++pos;
   }
   else
   {
    vec.push_back(atof(str.substr(pos2).c_str()));
    break;
   }     
  }
 }
 
 return vec.size();
}
 
//打印vector模板中的元素
template
inline void printvec(vector &vec)
{
 for (auto it = vec.begin(); it != vec.end(); ++it)
 {
  std::cout << *(it) << std::ends;
 }
 std::cout << std::endl;
}
 
 
//找到vector中最小值对应的下标
template
inline int getMinIndex(vector &vec)
{
 int min_index = 0;
 for (size_t index = 1; index < vec.size(); ++index)
 {
  if (vec[index] < vec[min_index])
  {
   min_index = index;
  }
 }
 return min_index;
}
 
//找到vector中最大值对应的下标
template
inline int getMaxIndex(vector &vec)
{
 int max_index = 0;
 for (size_t index = 1; index < vec.size(); ++index)
 {
  if (vec[index] > vec[max_index])
  {
   max_index = index;
  }
 }
 return max_index;
}
 
//获得最大间隙
template
T getMaxGap(int n,vector &vec)
{
 typedef struct bucket
 {
  T low;
  T high;
  bool hasnum;
 }bucket;
 
 int max_index = getMaxIndex(vec);
 int min_index = getMinIndex(vec);
 T maxnum = vec[max_index];
 T minnum = vec[min_index];
 T buck_len = (maxnum - minnum)*1.0 / (n-1);
 
 bucket* buck = new bucket[n - 1];
 memset(buck, 0, (n - 1)*sizeof(bucket));
 int buck_num(0);
 
 //将n个元素每个元素放置到对应的桶内
 buck[0].low = minnum; buck[0].high = minnum; buck[0].hasnum = true;
 buck[n - 2].low = maxnum; buck[n - 2].high = maxnum; buck[n - 2].hasnum = true;
 for (int i = 0; i < n; ++i)
 {
  if ((min_index == i) || (max_index == i))
   continue;
  //先判定元素是属于哪一个桶的,再确认其是不是桶内的最大或者最小元素
  buck_num = floor((vec[i] - minnum) / buck_len);
  if (false == buck[buck_num].hasnum)
  {
   buck[buck_num].high = vec[i];
   buck[buck_num].low = vec[i];
   buck[buck_num].hasnum = true;
  }
  else
  {
   if (vec[i]>buck[buck_num].high)
   {
    buck[buck_num].high = vec[i];
   }
   else if (vec[i] < buck[buck_num].low)
   {
    buck[buck_num].low = vec[i];
   }
  }
 }
 
 //在n-1个桶的边界找到最大间隔
 T maxgap = 0;
 T curgap=0;
 int pre_index = 0;    //上一个非空的桶的位置
 for (int i = 1; i <= n - 2;++i)
 {
  if (buck[i].hasnum)
  {
   curgap = buck[i].low - buck[pre_index].high;
   if (curgap > maxgap)
   {
    maxgap = curgap;
   }
   pre_index = i;
  }
 }
 
 delete[] buck;
 
 return maxgap;
}
 
//将数据写入output文件
template
inline int writefile(string filename, T n)
{
 ofstream ofile(filename.c_str(), ios_base::binary | ios_base::out);
 if (!ofile)
 {
  cerr << "cannot open file!\n";
  exit(1);
 }
 ofile << n;
 cout << "write over." << endl;
 return 0;
}
 
int main()
{
 string ifilename , ofilename;
 vector vec;
 cout << "input filename and ofilename:\n";
 cin >> ifilename >> ofilename;
 int n = readfile(ifilename, vec);
 double maxgap = getMaxGap(n, vec);
 writefile(ofilename, maxgap);
 
#if _Print_
 {
  printvec(vec);
  cout << maxgap;
  system("pause");
 }
#endif
 
 return 0;
}

你可能感兴趣的:(算法设计)