算法导论4--求最大和数组

  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 

运行结果:

原文地址:https://www.cnblogs.com/fkissx/p/4493114.html