博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
求最大子序列及其效率解析
阅读量:3533 次
发布时间:2019-05-20

本文共 5088 字,大约阅读时间需要 16 分钟。

#include 
#include
using namespace std;//s(tart)表示最大子序列的开始位置,e(nd)表示结束位置//这里如果有多于一个的最大子序列的时候,只记录开始位置最低的那个int s=0;int e=0;//穷举法,复杂度O(n^3)long maxSubSum1(const vector
&a){ long maxSum=0; for (int i=0; i
maxSum){ maxSum=thisSum; s=i; e=j; } } } return maxSum;}//也是穷举法,不过减去了上面的一些不必要操作O(n^2) long maxSubSum2(const vector
&a){ long maxSum=0; for (int i=0; i
maxSum){ maxSum=thisSum; s=i; e=j; } } } return maxSum;}long max3(long a, long b, long c){ if(a
c) return a; else return c;}long maxSumRec(const vector
a, int left, int right){ if(left == right) { //其实这个基准值在后面计算的时候可以保证 //在这里不必多此一举 if(a[left]>0) return a[left]; else return 0; } int center=(left+right)/2; long maxLeftSum=maxSumRec(a,left,center); long maxRightSum=maxSumRec(a,center+1,right); //某段序列中,求含最右侧元素序列和的最大值 long maxLeftBorderSum=0,leftBorderSum=0; for (int i=center; i>=left; i--) { leftBorderSum+=a[i]; if(leftBorderSum>maxLeftBorderSum) { maxLeftBorderSum=leftBorderSum; s=i; } } //某段序列中,求含最左侧元素序列和的最大值 long maxRightBorderSum=0,rightBorderSum=0; for (int j=center+1; j<=right; j++) { rightBorderSum+=a[j]; if(rightBorderSum>maxRightBorderSum) { maxRightBorderSum=rightBorderSum; e=j; } } return max3(maxLeftSum,maxRightSum, maxLeftBorderSum+maxRightBorderSum);}//该方法我们采用“分治策略”(divide-and-conquer),相对复杂的O(NlogN)的解法//最大子序列可能在三个地方出现,或者在左半部,或者在右半部,//或者跨越输入数据的中部而占据左右两部分。前两种情况递归求解,//第三种情况的最大和可以通过求出前半部分最大和(包含前半部分最后一个元素)//以及后半部分最大和(包含后半部分的第一个元素)相加而得到。long maxSubSum3(const vector
&a){ return maxSumRec(a,0,a.size()-1);}//如果a[i]是负数那么它不可能代表最有序列的起点,因为任何包含a[i]的作为起点的子//序列都可以通过用a[i+1]作为起点来改进。类似的有,任何的负的子序列不可能是最优//子序列的前缀。例如说,循环中我们检测到从a[i]到a[j]的子序列是负数,那么我们就可以推进i。//关键的结论是我们不仅可以把i推进到i+1,而且我们实际可以把它一直推进到j+1。long maxSubSum4(const vector
&a){ long maxSum=0; long thisSum=0; int t=0; for (int j=0; j
maxSum){ maxSum=thisSum; s=t; e=j; } else if(thisSum<0){ thisSum=0; t=j+1; } } return maxSum;}

测试程序:

#include 
#include
#include
#include
#include
#include
using namespace std;const long COUNT = 1000;const int MAX_NUM = 200;int Start = 0;int End = 0;bool readFile(vector
&input, string fileName){ ifstream infile(fileName.c_str()); if(!infile) { return false; } int s; while(infile >> s) { input.push_back(s); } return true;}bool writeTestData(string fileName){ ofstream outfile(fileName.c_str()); if(!outfile) { return false; } srand((unsigned)time(NULL)); for(int i = 0; i < COUNT; i++) { if(rand() % 2 == 0) { outfile << rand() % MAX_NUM << endl; } else { outfile << ~(rand() % MAX_NUM) <
& a){ long maxSum = 0; for(int i = 0; i < a.size(); i++) { for(int j = i; j < a.size();j++) { long thisSum = 0; for(int k = i; k <= j; k++) { thisSum += a[k]; } if(thisSum > maxSum) { maxSum = thisSum; Start = i + 1; End = j + 1; } } } return maxSum;}long maxSubSum2(const vector
& a){ long maxSum = 0; for(int i = 0; i < a.size(); i++) { long thisSum = 0; for(int j = i; j
maxSum) { maxSum = thisSum; Start = i + 1; End = j + 1; } } } return maxSum;}long max3(long a, long b, long c){ if(a < b) { a = b; } if(a > c) { return a; } else { return c; }}long maxSumRec(const vector
&a, int left, int right){ if(left == right) { if(a[left] > 0) { return a[left]; } else return 0; } int center = (left + right) / 2; long maxLeftSum = maxSumRec(a, left, center); long maxRightSum = maxSumRec(a, center + 1, right); long maxLeftBorderSum = 0, leftBorderSum = 0; for (int i = center; i >= left; i--) { leftBorderSum += a[i]; if (leftBorderSum > maxLeftBorderSum) { maxLeftBorderSum = leftBorderSum; Start = i + 1; } } long maxRightBorderSum = 0, rightBorderSum = 0; for(int j = center + 1; j <= right; j++) { rightBorderSum += a[j]; if(rightBorderSum > maxRightBorderSum) { maxRightBorderSum = rightBorderSum; End = j + 1; } } return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);}long maxSubSum3(const vector
&a){ return maxSumRec(a, 0, a.size() - 1);}long maxSubSum4(const vector
& a){ long maxSum = 0, thisSum = 0; for (int j = 0; j < a.size(); j++) { thisSum += a[j]; if (thisSum > maxSum) maxSum = thisSum; else if (thisSum < 0) thisSum = 0; } return maxSum;}int main(){ clock_t start,finish; vector
num; if(!writeTestData("in.txt")) { cout << "写入文件错误" << endl; } if(readFile(num, "in.txt")) { start = clock(); cout << maxSubSum1(num) << endl; finish = clock(); //cout << "Start position = " << Start << "\t" << "Start position = " << End <

count = 1000

4135

Time used = 12.87
4135
Time used = 0.06
4135
Time used = 0.00
4135
Time used = 0.00
请按任意键继续. . .

count = 2000

8968

Time used = 104.37
8968
Time used = 0.23
8968
Time used = 0.00
8968
Time used = 0.00
请按任意键继续. . .

count = 10000 //O(N^3)略去

15302

Time used = 5.88
15302
Time used = 0.02
15302
Time used = 0.00
请按任意键继续. . .

count = 100000

33853

Time used = 570.03
33853
Time used = 0.16
33853
Time used = 0.01
请按任意键继续. . .

!!!

转载地址:http://wxyhj.baihongyu.com/

你可能感兴趣的文章
N13-sqli盲注 基于时间型
查看>>
N1 技术心得 2019-6-26
查看>>
N1-环境配置
查看>>
N2-审计方法与步骤
查看>>
N3-常见的INI配置
查看>>
代码审计 N4 常见危险函数和特殊函数(一)
查看>>
MySQL笔记
查看>>
计算机运算方法之(原码 补码 反码 移码)
查看>>
计算机组成原理之(二进制与十进制互相转换,数的定点表示与浮点数表示)例题:设浮点数字长16位,其中阶码5位(含有1位阶符),尾数11位(含有1位数符)
查看>>
冒泡排序及其优化
查看>>
选择排序(java代码实现)
查看>>
插入排序
查看>>
哈夫曼树java代码实现
查看>>
快速排序
查看>>
vue路由高亮的两种方式
查看>>
vue router 报错: Uncaught (in promise) NavigationDuplicated {_name:""NavigationDuplicated"... 的解决方法
查看>>
vue跳转页面的两种方式
查看>>
存储器题目解析(持续更新中....)
查看>>
存储器知识要点
查看>>
Cache模拟器的实现
查看>>