您的位置:首页 > 其它

软件工程概论---环形一维数组最大子数组和

2015-04-14 22:43 218 查看
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,总结

在思考解决方法时不要执着于一个方法,要开阔思路,参考资料,多想想别的方式方法,一个好的方式方法解决问题更方便快捷。在我们拿上一个程序过来用的时候发现它不适合做这个更改,又采用了另一个人的原来的程序。每个人的程序有每个人的优点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: