1 #include<iostream> 2 #include<fstream> 3 #include<cstdlib> 4 using namespace std; 5 6 struct subArray{ 7 int low; 8 int high; 9 float sum; 10 }; 11 //分治策略 o(nlogn) 递归 12 void findMaxCross(float *A, int low,int mid,int high,subArray &temp)//找交叉最大数组 13 { 14 float leftsum=-9999; 15 float sum=0; 16 int i; 17 for(i=mid;i>=low;i--)//固定一端枚举另外一端 18 { 19 sum+=A[i]; 20 if(sum>leftsum) 21 { 22 leftsum=sum; 23 temp.low=i; 24 } 25 } 26 27 float rightsum=-9999; 28 sum=0; 29 for(i=mid+1;i<=high;i++) 30 { 31 sum+=A[i]; 32 if(sum>rightsum) 33 { 34 rightsum=sum; 35 temp.high=i; 36 } 37 } 38 temp.sum=leftsum+rightsum; 39 return; 40 } 41 42 void max_subArray(float *A, int low, int high, subArray &temp) 43 { 44 if(high==low) 45 { 46 temp.low=low; 47 temp.high=high; 48 temp.sum=A[low]; 49 return;//递归出口 50 } 51 int mid=(high+low)/2; 52 subArray left,right,cross; 53 max_subArray(A,low,mid,left);//二分策略递归 54 max_subArray(A,mid+1,high,right); 55 findMaxCross(A,low,mid,high,cross); 56 if (left.sum>=right.sum && left.sum>=cross.sum) 57 { 58 temp.low=left.low; 59 temp.high=left.high; 60 temp.sum=left.sum; 61 return; 62 } 63 else if (right.sum>=left.sum && right.sum>=cross.sum) 64 { 65 temp.low=right.low; 66 temp.high=right.high; 67 temp.sum=right.sum; 68 return; 69 } 70 else 71 { 72 temp.low=cross.low; 73 temp.high=cross.high; 74 temp.sum=cross.sum; 75 return; 76 } 77 } 78 79 //暴力搜索 o(n^2) 80 void max_subArray2(float *A, int low, int high, subArray &temp) 81 { 82 int i,j; 83 float initial=-9999,sum; 84 for(i=low;i<=high;i++)//固定一端枚举另一端 85 { 86 sum=0; 87 for(j=i;j<=high;j++) 88 { 89 sum+=A[j]; 90 if(sum>initial) 91 { 92 initial=sum; 93 temp.low =i; 94 temp.high=j; 95 temp.sum =sum; 96 } 97 } 98 } 99 } 100 101 //练习4.1-5 o(n) 递推的思想,不大于0的连续数的和都逐次扔掉 102 void max_subArray3(float *A, int low, int high, subArray &temp) 103 { 104 int i,cur_low=low; 105 int flag=0; 106 float sum=0,max=0; 107 for(i=low;i<=high;i++) 108 { 109 sum+=A[i]; 110 if (sum>=max)//找到和更大的连续子数组,替换 111 { 112 max=sum; 113 flag=1;//至少存在一个不小于0的数 114 temp.sum=sum; 115 temp.low=cur_low; 116 temp.high=i; 117 } 118 else if(sum<0)//前面的和小于0直接扔掉,重新计连续的数 119 { 120 sum=0; 121 cur_low=i+1; 122 } 123 } 124 if(flag==0)//若都是小于0的数组 125 { 126 int max=A[low],index=low; 127 for(i=low;i<=high;i++) 128 if(max<A[i]) 129 { 130 max=A[i]; 131 index=i; 132 } 133 temp.low=index; 134 temp.high=index; 135 temp.sum=max; 136 } 137 return; 138 } 139 140 int main() 141 { 142 float acord[1000]={0}; 143 int flag=2; 144 cout<<"文件读取输入 1 ,手动输入 2 :"; 145 cin>>flag; 146 int i=0; 147 if(flag==1) 148 { 149 ifstream fo; 150 fo.open("data.txt"); 151 if(!fo.is_open ()) 152 { 153 cout<<"could not open"<<endl; 154 exit(EXIT_FAILURE); 155 } 156 while(fo.good()) 157 { 158 fo>>acord[i]; 159 cout<<acord[i]<<" "; 160 i++; 161 } 162 if(fo.eof()) 163 cout<<"文件读取结束"<<endl; 164 else if(fo.fail()) 165 cout<<"数据类型不匹配"<<endl; 166 else 167 cout<<"未知错误"<<endl; 168 fo.close(); 169 } 170 else 171 { 172 cout<<"输入数组,#号结束"<<endl; 173 while(cin>>acord[i])i++; 174 } 175 cout<<"数据一共有"<<i<<"个"<<endl;//有几项数据 176 subArray result; 177 max_subArray3(acord,0,i-1,result); 178 for(i=result.low;i<=result.high;i++) 179 cout<<acord[i]<<" ";//最大数组项 180 cout<<endl<<"最大和"<<result.sum<<endl; 181 182 return 0; 183 }
输入数据:13 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7
运行结果: