求一维数组的最大子数组2(结对开发)
题目:返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大。
同时返回最大子数组的位置。
求所有子数组的和的最大值。
结对开发的伙伴:
博客名:Mr.缪
姓名:缪金敏
链接:http://www.cnblogs.com/miaojinmin799/
分析:这是在第四次程序的基础上再加了首尾链接,所以我在原先的基础上把输入的数组有重新在数组末尾再生成了一遍,在动态规划外围再加一个循环,从而实现计算A[0]-A[n]或者A[1]-A[n]-A[0]等等最大值计算,然后用一个数组记录最大值和还有起始地址和结尾地址。然后输出子数组。
代码:
1 //求一维数组的最大子数组2 王文奇 缪金敏 2016/3/26 2 #include<iostream> 3 using namespace std; 4 5 int max(int a, int b) //返回a和b中的最大值 6 { 7 if (a > b) 8 { 9 return a; 10 } 11 else 12 { 13 return b; 14 } 15 } 16 17 int main() 18 { 19 int Array[10000]; 20 int i = 1; 21 int dynamic_planning[10000][2], j, sum[10000]; 22 int start[10000] = { 0 }; //最大子数组的起始位置 23 int end[10000] = { 0 }; //最大子数组的终止位置 24 cout << "请输入一组一维数组(回车结束):" << endl; 25 cin >> Array[0]; 26 while (cin.get() != '\n') //回车结束 27 { 28 cin >> Array[i++]; 29 } 30 for (j = i; j < 2 * i; j++) //数组末尾再生成了一遍 31 { 32 Array[j] = Array[j - i]; 33 } 34 int n = 0; 35 36 //动态规划数组初始化 37 while (true){ 38 dynamic_planning[0][0] = 0; 39 dynamic_planning[0][1] = Array[n]; 40 for (j = 1; j<i; j++) 41 { 42 dynamic_planning[j][0] = max(dynamic_planning[j - 1][0], dynamic_planning[j - 1][1]); 43 dynamic_planning[j][1] = max(Array[j + n], (dynamic_planning[j - 1][1] + Array[j + n])); 44 //开始下标的条件:数组第二列的数前一个比现在的小且小于0且第一列的数小于等于第二列 45 if (dynamic_planning[j - 1][1] < dynamic_planning[j][1] && dynamic_planning[j - 1][1]<0 && dynamic_planning[j][0] <= dynamic_planning[j][1]) 46 { 47 start[n] = j + n; 48 //cout << "start:"<<start << endl; 49 } 50 //结束下标的条件1:当前的算出的最大子数组+输入的值比下一步的最大值大于或等于 51 if (dynamic_planning[j - 1][1] >= dynamic_planning[j][0]) 52 { 53 end[n] = j - 1 + n; 54 //cout << "end:" << end << endl; 55 } 56 //结束下标的条件2:第二列的数大于等于第一列 57 if (dynamic_planning[j][1] >= dynamic_planning[j][0]) 58 { 59 end[n] = j + n; 60 //cout << "end:" << end << endl; 61 } 62 63 } 64 sum[n] = max(dynamic_planning[i - 1][0], dynamic_planning[i - 1][1]); 65 n++; 66 if (n == i) 67 { 68 break; 69 } 70 } 71 int max = sum[0]; 72 n = 0; 73 for (j = 0; j < i; j++) 74 { 75 if (sum[j]>max) 76 { 77 max = sum[j]; 78 n = j; 79 } 80 } 81 cout << "最大的子数组为:" << endl; 82 if (start[n] <= end[n]) 83 { 84 for (j = start[n]; j <= end[n]; j++) 85 { 86 cout << Array[j] << " "; 87 } 88 } 89 else 90 { 91 for (j = start[n]; j < i; j++) 92 { 93 cout << Array[j] << " "; 94 } 95 for (j = 0; j <= end[n]; j++) 96 { 97 cout << Array[j] << " "; 98 } 99 } 100 cout << endl; 101 cout << "起始索引: " << start[n]; 102 if (end[n] >= i) 103 cout << "终止索引: " << end[n] - i; 104 else 105 cout << "终止索引: " << end[n]; 106 cout << endl; 107 //cout << start << " " << end << endl; 108 109 cout << "最大的子数组的和为:" << sum[n] << endl; 110 return 0; 111 }
运行结果截图:
总结:
这一次练习只是在上一次基础上多加了一次循环,所以相对较为简单。
项目计划总结:
时间记录日志:
缺陷记录日志: