成員:林彥汝、張金
題目:
返回一個整數數組中最大子數組的和。
要求:
要求程序必須能處理1000 個元素;
每個元素是int32 類型的;
輸入一個整形數組,數組里有正數也有負數。
數組中連續的一個或多個整數組成一個子數組,每個子數組都有一個和。
求所有子數組的和的最大值。
(我主要負責程序分析,代碼編程;張金負責代碼復審,代碼測試計划。)
思路:
通過第一次求一個一維數組中最大子數組的和,在此基礎上我們做了擴展。前面在程序中我們固定了數組的長度,默認為5,而這次則按題目要求擴展到1000,定義數值類型為int32。讓程序隨機產生1000個數,用同樣的方法求子數組和的最大值。
剛看完題目時感覺不難,所以改動的地方不多,通過幾次測試下來卻發現了不少問題(在運行結果截圖部分有分析說明)。
源代碼:
#include<iostream.h>
#include<stdlib.h>
#define AMOUNT 1000
int main()
{
long int arr[AMOUNT];
long int arrCopy[AMOUNT];
long int max[AMOUNT];
int i,j;
int n;
int start,rear; //子數組的開始,結束
int mount=AMOUNT;
for(i=0;i<mount;i++)
{
try
{
n=rand()%2;
if(n==0)
{
arr[i]=rand();
arrCopy[i]=arr[i];
max[i]=arr[i];
}
else
{
arr[i]=-rand();
arrCopy[i]=arr[i];
max[i]=arr[i];
}
}
catch(long int e)
{
cout<<"Long Inter=ger Exception!"<<endl;
}
}
cout<<"Array :"<<endl;
for(i=0;i<mount;i++)
{
cout<<arr[i]<<" ";
if((i+1)%10==0)
{
cout<<endl;
}
}
for(j=0;j<mount-1;j++)
{
for(i=j+1;i<mount;i++)
{
try
{
arr[j]=arr[j]+arr[i];
if(max[j]<arr[j])
{
max[j]=arr[j];
rear=i+1;
}
}
catch(long int e)
{
cout<<"Long Inter=ger Exception!"<<endl;
}
}
}
for(i=0;i<mount;i++)
{
if(max[0]<max[i])
{
max[0]=max[i];
start=i+1;
}
}
cout<<endl;
cout<<"從第"<<start<<"個數"<<arrCopy[start-1]<<"開始"<<endl;
cout<<"到第"<<rear<<"個數"<<arrCopy[rear-1]<<"結束"<<endl;
cout<<"子數組和的最大值為: "<<max[0]<<endl;
return 0;
}
運行結果:
(1)運行了幾次(由於1000個數顯示了100行,故只截取部分顯示結果),由截圖可以看到,很明顯地隨機產生的1000個數全部為正,沒有負數。
(2)修改代碼,通過隨機產生0和1,來控制正數和負數的產生,避免只出現正數或者只出現負數的情況。
運行后又發現問題:因為有1000個數且數值都很大,我們並不能直接看出結果是否正確。
(3)完善程序,將子數組的位置找出來,再進行校驗。
發現數值的范圍還是很大,並且隨機產生的數和最后相加的結果范圍是不是超出了int32數據類型的范圍(即是否數值越界),而C++本身在調試過程中是沒有錯誤提示的,用異常處理來捕捉:
try
{
...
}
catch(long int e)
{
cout<<"Long Inter=ger Exception!"<<endl;
}
總結:
之前做的數組長度我們在測試時一般都填得很小,並且給每個元素的賦值也不超過兩位數,甚至是固定了,都是為了方便直接找到一個和是最大的子數組,這都不能測試出程序哪里有不足,無論是數量還是數值的大小。通過隨機產生的1000個數據我們發現了問題。因為已經把時間復雜度的概念給徹底忘了,這個程序也就沒有考慮。
在調試中我的收獲很大,以上截圖都是調了很多次才改好了一個缺陷,因為數據很多,循環和嵌套就比較復雜,start和rear兩個參數在開始添加時頻繁出錯,就先把數量改小,后運用單步調試到底看出錯在哪一步,並且用異常處理來提示我們是否有數值越界等一些軟件調試時不考慮的缺陷。
此次結對開發沒有第一次合作得好,因為覺得改動不大所以討論得還是比較少,個人的主觀看法比較多,以后還是多交流吧。