1,题目要求
求一维数组的最大子数组和,首尾相连成环形,数组包含正数和负数两种。
输出最大子数组的位置。
结对开发成员:朱慧敏,郭婷
2,思路设计
一开始的思路是把原来的数组进行扩充,即n个数的数组长度变成了2*n-1。这个思路很普遍也简单。后来
我们又参考了百度,发现了求余的方法,更加简单。(如果所有数都是负的,需要加一个判断。)
3,代码
#include<iostream> #include<cmath> using namespace std; #define N 1000 #define max(a,b)(a>b?a:b) int MaxSum_base(int arr[], int n) { int i, sum = 0; int max = arr[0]; for (i = 0; i<n; i++) { if (sum <= 0) { sum = arr[i]; } else { sum = sum + arr[i]; } if (sum>max) { max = sum; } } return max; } int MaxSum_linked(int arr[], int n) { int c = arr[0]; int ans = c; bool h = false; for (int i = 1; i < n * 2 - 1; i++) { if (i < n&&arr[i] < 0) h = true; c = max(c + arr[i%n], arr[i%n]); ans = max(ans, c); if (i == n - 1 && !h) return ans; } return ans; } void MaxSum_location(int * arr, int n, int & start,int &end) { int maxSum = -N; int sum = 0; int cstart = start = 0; //cstart记录每次当前起始位置 for (int i = 0; i < n; ++i) { if (sum < 0) { sum = arr[i]; cstart = i; // 记录当前的起始位置 } else { sum += arr[i]; } if (sum > maxSum) { maxSum = sum; start = cstart; // 记录并更新最大子数组起始位置 end = i; } } } int main() { int i=0, n, a[100],s,e; cout << "输入数组个数:"; cin >> n; cout << "请输入数组:"; for (i = 0; i < n; i++) { cin >> a[i]; } int x = MaxSum_base(a, n); cout << ">>线性最大子数组的和为:" << x << endl; int sum = MaxSum_linked(a, n); cout << ">>环形最大子数组的和为:" <<sum<< endl; MaxSum_location(a,n,s,e); cout << "最大子数组的位置是:" <<"第"<< s+1<<"个到第"<< e << "个" <<endl; }
4,截图
5,总结
在思考解决方法时不要执着于一个方法,要开阔思路,参考资料,多想想别的方式方法,一个好的方式方法解决问题更方便快捷。在我们拿上一个程序过来用的时候发现它不适合做这个更改,又采用了另一个人的原来的程序。每个人的程序有每个人的优点。