• 算法导论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 

    运行结果:

  • 相关阅读:
    devexpress toolbar 填充整行宽度
    2. Rust的三板斧 安全,迅速,并发
    1. rust的优点
    谈谈我对sku的理解(3)----页面效果
    谈谈我对sku的理解(2)----数据库设计
    谈谈我对sku的理解(1)
    我眼里的奇酷手机360OS
    Oracle中的wm_concat()函数
    获取java本地系统信息 Properties
    java 获取用户的ip都是 127.0.0.1
  • 原文地址:https://www.cnblogs.com/fkissx/p/4493114.html
Copyright © 2020-2023  润新知