《算法导论》课后题--5--第四章(0)
来源:互联网 发布:奥数优化训练22讲 编辑:程序博客网 时间:2024/06/05 21:04
4.1-1
分析:
当A的所有元素都为负数时,该函数返回数组中的最大元素和该元素的下标。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.1-2
分析:该题是对课本内容的小练习,继续学习伪代码书写;
作答:
//输入:待查找的数组A//输出:最大子数组的下标范围及和FIND-MAXIMUM-SUBARRAY(A)1low = 1//low用来存储最大子数组的下界2high = 1//high用来存储最大子数组的上界3maxSum = 负无穷//存储最大子数组的和4for i = 1 to A.length5sum = 0//累计当前求和结果6for j = i to A.length7sum += A[j]8if sum > maxSum9maxSum = sum10low = i11high = j12return (low, high, maxSum)
两层循环嵌套,容易求得渐进时间复杂度为:。-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.1-3
分析:考查将伪代码转化成程序,并对现有算法进行复合改进;
作答:
#include <iostream>#include <vector>#include <ctime>using namespace std;//计算函数时间clock_t beginA, endA, beginB, endB;double durationA, durationB;void findMaximumSubarray(vector<int> &A, int &low, int &high, int &maxSum){ low = 1; high = 1; maxSum = -999999; for (int i = 0; i < A.size(); ++i) { int sum = 0; for (int j = i; j < A.size(); ++j) { sum += A[j]; if (sum > maxSum) { maxSum = sum; low = i; high = j; } } }}void findMaxCrossingSubarray(vector<int> &A, int low, int mid, int high, int &maxLeft, int &maxRight, int &maxSum){ int leftSum = -999999; int sum = 0; for (int i = mid; i >= low; --i) { sum += A.at(i); if (sum > leftSum) { leftSum = sum; maxLeft = i; } } int rightSum = -999999; sum = 0; for (int j = mid + 1; j <= high; ++j) { sum += A.at(j); if (sum > rightSum) { rightSum = sum; maxRight = j; } } maxSum = leftSum + rightSum;}void findMaximumSubarray(vector<int> &A, int low, int high, int &fLow, int &fHigh, int &fSum){ if (high == low) { fLow = low; fHigh = low; fSum = A.at(low); } else { int mid = (low + high) / 2; int leftLow, leftHigh, leftSum; findMaximumSubarray(A, low, mid, leftLow, leftHigh, leftSum); int rightLow, rightHigh, rightSum; findMaximumSubarray(A, mid + 1, high, rightLow, rightHigh, rightSum); int crossLow, crossHigh, crossSum; findMaxCrossingSubarray(A, low, mid, high, crossLow, crossHigh, crossSum); if (leftSum >= rightSum && leftSum >= crossSum) { fLow = leftLow; fHigh = leftHigh; fSum = leftSum; } else if (rightSum >= leftSum && rightSum >= crossSum) { fLow = rightLow; fHigh = rightHigh; fSum = rightSum; } else { fLow = crossLow; fHigh = crossHigh; fSum = crossSum; } }}int main(int argc, char *argv[]){ //vector<int> A{ 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 }; for(int i = 10 ; i < 300 ; ++i) { vector<int> A(i, 1); vector<int> B = A; //测试暴力算法 int Alow, Ahigh, Asum; beginA = clock(); findMaximumSubarray(A, Alow, Ahigh, Asum); endA = clock(); durationA = double(endA - beginA) / CLK_TCK; //测试递归算法 int Blow, Bhigh, Bsum; beginB = clock(); findMaximumSubarray(B, 0, B.size() - 1, Blow, Bhigh, Bsum); endB = clock(); durationB = double(endB - beginB) / CLK_TCK; if((endA - beginA) == (endB - beginB)) { cout << "when input scale is i = " << i << endl; cout << "sum: " << Asum << " ,and runtime is : " << durationA << endl; cout << "sum: " << Bsum << " ,and runtime is : " << durationB << endl; } } return 0;}测试结果:(只显示了最后一次输出的结果),大约在当数组规模是230左右时,两种算法计算时间相当。
编译环境:Qt Creator + VS2015
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.1-4
分析:对算法进行改进;
作答:
伪代码:
//当数组中的元素都为负数时,返回空数组,//此时返回的下标low > high,注意把函数输入下标和返回下标不要混淆FIND-MAXIMUM-SUBARRAY(A, low, high)1if high == low2if A[low] >= 03return (low, high, A[low])4else return (low, high-1, 0) //此时low > high,表示返回空数组5else mid = (low + high) / 26(left-low, left-high, left-sum) = FIND-MAXIMUM-SUBARRAY(A, low, mid)7(right-low, right-high, right-sum) = FIND-MAXIMUM-SUBARRAY(A, mid+1, high)8(cross-low, cross-high, cross-sum) = FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)9if left-sum >= right-sum and left-sum >= cross-sum10return (left-low, left-high, left-sum)11elseif right-sum >= left-sum and right-sum >= cross-sum12return (right-low, right-high, right-sum)13else return (cross-low, cross-high, cross-sum)FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)1left-sum = 02max-left = mid + 13sum = 04for i = mid downto low5sum += A[i]6if sum >= left-sum//等号保证出现0元素时返回07left-sum = sum8max-left = i9right-sum = 010max-right = mid11sum = 012for j = mid+1 to high13sum += A[j]14if sum >= right-sum15right-sum = sum16max-right = j17return (max-left, max-right, left-sum + right-sum)代码实现:
#include <iostream>#include <vector>using namespace std;void findMaxCrossingSubarray(vector<int> &A, int low, int mid, int high, int &maxLeft, int &maxRight, int &maxSum){ int leftSum = 0; maxLeft = mid + 1; int sum = 0; for (int i = mid; i >= low; --i) { sum += A.at(i); if (sum >= leftSum) { leftSum = sum; maxLeft = i; } } int rightSum = 0; maxRight = mid; sum = 0; for (int j = mid + 1; j <= high; ++j) { sum += A.at(j); if (sum >= rightSum) { rightSum = sum; maxRight = j; } } maxSum = leftSum + rightSum;}void findMaximumSubarray(vector<int> &A, int low, int high, int &fLow, int &fHigh, int &fSum){ if (high == low) { if(A.at(low) >= 0) { fLow = low; fHigh = low; fSum = A.at(low); } else { fLow = low; fHigh = high - 1; fSum = 0; } } else { int mid = (low + high) / 2; int leftLow, leftHigh, leftSum; findMaximumSubarray(A, low, mid, leftLow, leftHigh, leftSum); int rightLow, rightHigh, rightSum; findMaximumSubarray(A, mid + 1, high, rightLow, rightHigh, rightSum); int crossLow, crossHigh, crossSum; findMaxCrossingSubarray(A, low, mid, high, crossLow, crossHigh, crossSum); if (leftSum >= rightSum && leftSum >= crossSum) { fLow = leftLow; fHigh = leftHigh; fSum = leftSum; } else if (rightSum >= leftSum && rightSum >= crossSum) { fLow = rightLow; fHigh = rightHigh; fSum = rightSum; } else { fLow = crossLow; fHigh = crossHigh; fSum = crossSum; } }}int main(int argc, char *argv[]){ vector<int> A(10, -1); int Alow, Ahigh, Asum; findMaximumSubarray(A, 0, A.size() - 1, Alow, Ahigh, Asum); cout << "The maximum subarray is : "; if(Alow > Ahigh) { cout << "null array!!!"; } else { for(int i = Alow ; i <= Ahigh ; ++i) { cout << A.at(i) << " "; } } cout << endl << "The sum is : " << Asum << endl; return 0;}输出结果:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
好了,这一篇先到这里。下午继续。。。
加油!!!
- 《算法导论》课后题--5--第四章(0)
- 《算法导论》课后题--6--第四章(1)
- 《算法导论》课后题--7--第四章(2)
- 《算法导论》课后题--1--第二章(0)
- 《算法导论》系列课后思考题之-第四章《递归式》
- 算法导论第四章4.1节代换法课后答案
- 算法导论第四章4.2递归式课后答案
- 算法导论第四章4.3主方法课后答案
- 算法导论课后习题解析 第四章 下
- 算法导论课后习题解析 第四章 上
- 算法导论(三版):第二章第一节课后题
- 《算法导论》课后题--2--第二章(1)
- 《算法导论》课后题--3--第二章(2)
- 《算法导论》课后题--4--第三章
- 《算法导论》课后题--0--第一章
- 算法导论--第四章--练习4.1-5
- 《算法导论》第四章-思考题(参考答案)
- 算法导论课后习题第二章(1)
- git项目添加.gitigore文件
- django中语言设置的问题
- 使用generator自动生成Mybatis映射配置文件
- Java基础知识随笔
- 数据结构之单链表(头插法)
- 《算法导论》课后题--5--第四章(0)
- windows 安装 tensorflow
- 练习
- USACO
- HDU 2177 取(2堆)石子游戏
- 字符集
- 机器学习-周志华-个人练习10.1
- 个人学习(三)
- css3布局的若干笔记总结