文章标题

来源:互联网 发布:strtoupper php 编辑:程序博客网 时间:2024/05/19 12:17

问题描述

最大间隙问题:给定n个实数x1,x2,…,xn,求这n个实数 在实轴上相邻2个数之间的最大差值(线性时间)。

算法思路

  1. 找到n个数据中最大和最小数据max和min;
  2. 用n-2个点等分区间[min,max],即将[min,max]等分为n-1个区间(前闭后开区间),将这些区间看做桶,桶的结构体分为max,min和flag,分别表
    示桶里的最大、最小和是否是空桶,编号为1,2,…,n-2,n-1,且桶i的上界和桶i+1的下界相同,即每个桶的大小相同,每个大小为: offset=(maxmin)/(
    n-1);
  3. 将n个数放入n-1个桶中:按如下规则将x[i]分配到某个桶(编号pos)中: pos = int((array[i] - min)/offset);
  4. 求最大间隙:除最大最小数据max和min以外的n-2个数据被放入n-1个桶中,因此至少有一个桶是空的,又因肯定有空桶存在,所以最大间隙不会
    在同一桶中出现,而是在空桶两侧!又因求的是实数轴相邻两数的差值,因此和空桶两侧桶中间的数无关,即最大间隙在桶i的上界和桶j的下界之
    间产生(j>=i+1)。为了遍历方便,将空桶删除,然后遍历一遍得到最大的间隔。

代码

C++

#include <iostream>#include <fstream>#include <string>using namespace std;struct Barrel{    double min;   //桶中最小的数    double max;   //桶中最大的数    bool flag = false;    //判断桶中是否有数据};double BarrelOperation(double * array, int n){    Barrel  *barrel = new Barrel[n];     Barrel *tmp = new Barrel[n];  //临时桶    int i = 0;    double arrayMax = array[0], arrayMin = array[0];    //遍历一遍,求最大最小值    for (i = 0; i < n; i++){        if (array[i] >= arrayMax)            arrayMax = array[i];        if (array[i] <= arrayMin)            arrayMin = array[i];    }    double offset = (arrayMax - arrayMin) / (n - 1); //所有数的平均间隔,即桶的大小    //对桶进行初始化    tmp[0].min = arrayMin;    tmp[n - 2].max = arrayMax; //只有n-1个桶    //对数据进行分桶    for (i = 0; i < n ; i++){        int pos = (int)((array[i] - arrayMin) / offset); //数据对应的桶        if (!tmp[pos].flag){            tmp[pos].max = tmp[pos].min = array[i];            tmp[pos].flag = true;        }        else{            if (array[i] > tmp[pos].max){                tmp[pos].max = array[i];            }            if (array[i] < tmp[pos].min){                tmp[pos].min = array[i];            }        }    }    int nBarrel = 0; //实际使用桶的数目    for (i = 0; i < n; i++){        if (tmp[i].flag){            barrel[nBarrel++] = tmp[i];        }    }    double maxOffset = 0.0;  //最大间隔    for (i = 0; i < nBarrel-1; i++){        if ((barrel[i + 1].min - barrel[i].max) > maxOffset)            maxOffset = barrel[i + 1].min - barrel[i].max;    }    return maxOffset;}void main(){    int n ;    double *arrayNum;    //读入数据    FILE *fp = fopen("input.txt", "r");    if (fp == NULL)        printf("can not open file...");    //读入数据个数    fscanf(fp, "%d", &n);  //facanf遇到空格和换行时结束    arrayNum = new double[n];    for (int i = 0; i < n; i++)        fscanf(fp, "%lf", &arrayNum[i]);    fclose(fp);    double maxOffset = BarrelOperation(arrayNum, n);    //结果输出    ofstream outfile;    outfile.open("output.txt");    outfile << maxOffset << endl;    outfile.close();}
0 0
原创粉丝点击