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

运行结果:

时间: 2024-12-29 23:25:56

算法导论4--求最大和数组的相关文章

Python算法与数据结构--求所有子数组的和的最大值

Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室?昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 这个题目有多个解法,比如可以用一个二维数组存之前每个数据的和,然后在进行大小比较:但是这样时间负责度就是O(n2)了. 换个思路思考下,因为是要最大数,那么就不需要存储,只需要找最大值就可以了.但是为了找子序列的最大和,在遇到

算法导论3:最大子数组问题 2016.1.3

顶着期末复习的压力,还是在今天过完之前看完了一个算法——最大子数组问题. <算法导论>中引入这个问题是通过股票的购买与出售,经过问题转换(转换的过程比较简单,但是不好想),将前一天的当天的股票差价重新表示出来,即转为了一个最大子数组的问题 ,具体内容是:   13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7   找到这连续的16个数里面的连续和最大的子数组;   书中差不多是这个意思:假定我们要寻找子数组A[lo

算法导论 10.1-2 用一个数组实现两个栈

一.题目 用一个数组A[ 1....N ]实现两个栈,除非数组的每一个单元都被使用,否则栈例程不能有溢出,注意PUSH和POP操作的时间应为O(1). 二.解法 对于一个数组,由它的两端作为栈底,栈向数组中间扩展.当数组中每个元素被用到时,栈满. 三.代码 struct Node; typedef Node *ComStack; struct Node { int Capacity; int TopL; int TopR; ElementType *Array; }; ComStack Crea

算法导论 4.1 最大子数组问题

8. 实现代码 1 #include <iostream> 2 using namespace std; 3 4 const long long NINF = -1 << 30; 5 const int N = 100; 6 struct ans { 7 long long sum; 8 int left; 9 int right; 10 }; 11 12 13 ans FIND_CROSS_MAX_SUBARRAY(int a[], int low,int mid, int hi

【算法导论学习-016】两个已排过序的等长数组的中位数(median of two sorted arrays)

问题来源 <算法导论>P223 9.3-8: Let X[1..n] and Y[1..n] be two arrays, each containing nnumbers already in sorted order. Give an O(lgn)-time algorithm to find themedian of all 2n elements in arrays X and Y. 翻译过来即:求两个等长(n个元素)的已排序数组A和B的中位数 方案1:对两个数组进行归并直到统计到第n

算法题:求数组中最小的k个数

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:输入n个整数,找出其中最小的k个数. <剑指offer>给出了两种实现算法: 算法1:采用Partition+递归法,该算法可以说是快速排序和二分查找的有机结合.算法的时间复杂度为O(n),缺点在于在修改Partition的过程中会修改原数组的值. 算法2:采用top-k算法.如果要找最小的K个数,我们才用一个含有K个值的大顶堆:如果要找最大的K个数,我们采用小顶堆.该算法的时间复杂度为O(nlogK),是一种比较好的算法,启发于堆排序

算法学习(3)----求数组中大小最接近的两个元素的差

<算法设计与分析基础>习题1.2 第 9 题如下: 考虑下面这个算法,它求的是数值数组中大小最接近的两个元素的差. 算法: MinDistance(A[0..n-1]) //输入:数字数组 A[0..n-1] //输出:数组中两个大小相差最少的元素的差值 dmin <- ∞ for i <- 0 to n-1 do for j <- 0 to n-1 do if i≠j and |A[[i]-A[j]| < dmin dmin <- |A[i]-A[j]| ret

【算法导论学习-015】数组中选择第i小元素(Selection in expected linear time)

1.算法思想 问题描述:从数组array中找出第i小的元素(要求array中没有重复元素的情况),这是个经典的"线性时间选择(Selection in expected linear time)"问题. 思路:算法导论215页9.2 Selection in expect linear time 2.java实现 思路:算法导论216页伪代码 /*期望为线性时间的选择算法,输入要求,array中没有重复的元素*/ public static int randomizedSelect(i

Java实现:求子数组的最大和(数组)

求子数组的最大和(数组) 题目: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为 O(n). 例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,因此输出为该子数组的和 18. 解题思路: 我觉得用户关心的的数据有两个,一个是子数组的和,还有一个是子数组具体有哪些元素,所以我们可以封装一个子数组类SubArray,成员有子数据开

快速求两个数组交集算法

快速求出两个数组的交集的算法,如果用循环遍历的方法,其时间复杂度为O(N^N),在面试中一般不考虑这种方法. 这里提供一种快速算法,算法实现步骤如下: 1. 找到arr1的最大数max,创建一个max+1大小的数组result. 2. 以arr1中的值作为result的下标,该索引处的值+1. 3. 在result数组中遍历arr2中的值为下标处的值,如果该索引值不为0,则代表该值是两者的交集,保留. 程序实现如下: /** * 求两个数组的交集 * @param arr1 * @param a