最大间隙问题

来源:互联网 发布:windows安装在bootcamp 编辑:程序博客网 时间:2024/05/01 07:42

转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/44686781

  • 问题描述
  • 算法设计
  • 数据输入
  • 结果输出
  • 算法设计思想
  • 算法实现

问题描述

最大间隙问题:给定 n 个实数x1,x2,…,xn,求这 n 个数在实轴上相邻 2 个数之间的最大差值。假设对任何实数的下取整函数耗时 O(1),设计解最大间隙问题的线性时间算法。

算法设计

对于给定的 n 个实数x1,x2,…,xn,计算它们的最大间隙。

数据输入

输入数据由文件名为 input.txt 的文本文件提供。文件的第 1 行有 1 个正整数n。接下来的 1 行中有 n 个实数x1,x2,…,xn。

结果输出

将找到的最大间隙输出到文件 output.txt。


这里写图片描述

算法设计思想

问题要求相邻两点之间的最大间隙,很自然的想法当然是先排序,这样就很容易的求出最大间隙,但是由前面博客的内容可以知道,比较排序问题的时间复杂度下限是O(nlogn),不符合题设要求的线性时间复杂度的要求,所以这里我们考虑分治思想。

  • 找到 n 个数据中最大和最小数据 max 和 min ;
  • 将 max-min 的长度平均分为 n-1 份,这里将这 n-1 个线段叫做 n-1 个桶,由组合数学的抽屉原理可知,剩下的 n-2 个元素将必将落在这 n-1 个桶里,并且肯定有一个桶是空的(除了min和max)。

这里有个规律,同一个桶内的数之间的间隙都小于等于桶的大小,而相邻两个非空桶边界(这里的桶的边界指的是桶里最大和最小的数)之间的间隙肯定有一个大于等于桶的大小(因为n-1个桶里至少有一个空桶)。所以,一定是某个桶的上界(high)和其后某个桶的下界(low)之间隙,且该两桶之间的桶(即编号在该两桶编号之间的桶)一定是空桶,即最大间隙在桶 i的上界和桶 j 的下界之间产生 ( j >= i+1 )。


算法实现

具体代码如下所示:

#ifndef MAXGAP_H_INCLUDED#define MAXGAP_H_INCLUDEDclass MaxGap{public:    int count;//数据个数    double maxGap;//最大间隙    double *num;//存放数据的数组    MaxGap(const char *filename);    ~MaxGap();    double getMaxGap(int n, double *arr);};int minIndex(int n, double *arr);int maxIndex(int n, double *arr);void menu();#endif

#include<fstream>#include "MaxGap.h"/*****************读入数据*****************/MaxGap::MaxGap(const char *filename){    FILE *fp = fopen(filename, "r");    if (fp == NULL){        printf("can't open the file!");        exit(0);    }    fscanf(fp,"%d",&count);//读取文件第一行数据    num = new double[count];    for (int i=0; i<count; i++)        fscanf(fp,"%lf",&num[i]);//读取文件第二行数据    maxGap = 0;    fclose(fp);}MaxGap::~MaxGap(){    delete[] num;    num = NULL;}/**********************************获取num数组中一串数据的最大间隙**********************************/double MaxGap::getMaxGap(int n, double *arr){    int min = minIndex(n,arr);    double minNum = arr[min];//数组中最小值    int max = maxIndex(n,arr);    double maxNum = arr[max];//数组中最大值    double avrGap = (maxNum - minNum)/(n-1);//等分为n-1个区间(1~n-1)    int *blockNum = new int[n];//存放每个区间的数据个数    double *low = new double[n];//存放每个区间的最小值    double *high = new double[n];//存放每个区间的最大值    for (int i=0; i<n; i++){//初始化        blockNum[i] = 0;        low[i] = maxNum;        high[i] = minNum;    }    int index;//桶编号    for (int i=0; i<n; i++){//设置n-1个区间中的最大最小值        index = int((arr[i]-minNum)/avrGap)+1;        if (index == n)            index--;//maxNum放入第n-1个区间中        blockNum[index]++;        if(arr[i] < low[index])            low[index] = arr[i];        if (arr[i] > high[index])            high[index] = arr[i];    }    /*除最大最小值外,n-2个元素放入n-1个区间,至少有一个空区间*/    double tempMaxGap = 0, tempHigh = high[1], tempGap;    for (int i=2; i<n; i++){        if (blockNum[i]){//i区间非空            tempGap = low[i] - tempHigh;            if (tempGap > tempMaxGap)                tempMaxGap = tempGap;            tempHigh = high[i];        }    }    maxGap = tempMaxGap;//获得最大间隙!    delete[] blockNum;blockNum = NULL;    delete[] low;low = NULL;    delete[] high;high = NULL;    return maxGap;}/************************获取数组最小数据的下标************************/int minIndex(int n, double *arr){    int index;    double temp = arr[0];    for (int i=1; i<n; i++){        if (arr[i] < temp){            temp = arr[i];            index = i;        }    }    return index;}/************************获取数组最大数据的下标************************/int maxIndex(int n, double *arr){    int index;    double temp = arr[0];    for (int i=1; i<n; i++){        if (temp < arr[i]){            temp = arr[i];            index = i;        }    }    return index;}void menu(){    printf("-----------------------------------\n");    printf("input command to test the program\n");    printf(" i or I : input filename to test\n");    printf(" q or Q : quit\n");    printf("------------------------------------\n");    printf("$ input command >");}

#include <iostream>#include <string.h>#include "MaxGap.h"#define FILE_NAME_LENGTH 50using namespace std;int main(){    char input[10];    char filename[FILE_NAME_LENGTH];    FILE *f = fopen("output.txt","w");    menu();    scanf("%s",input);    while(stricmp(input,"q") != 0){        if (stricmp(input,"i") == 0){            printf("please input the filename:");            scanf("%s",filename);            MaxGap gap(filename);            double answer = gap.getMaxGap(gap.count,gap.num);            printf("Max Gap is: %.2f\n",answer);            fprintf(f,"%.2f",answer);        }        printf("$input command >");        scanf("%s",input);    }    fclose(f);    return 0;}

实验结果截图如下 :


这里写图片描述


转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/44686781

源码下载

0 0