数据结构与算法分析_数组的子序列问题

<span style="font-family:Arial;">/**
	*2.17
	*求最小子序列和,最小正子序列和,最大子序列乘积
	*
	*/	
#include <iostream>
#include <algorithm>  
using namespace std;
#define INT_MIN -32768
#define INT_MAX 32767
//在里面有使用#define和const定义常量的比较,推荐使用const
//#define LEN 10
const int LEN = 10;

/**
	*最大子序列和
	*
	*/
int subMaxSum(int *a, int length){
	int thismax = 0, max=INT_MIN;
	for(int i=0; i<length; i++){
		thismax += a[i];
		if(thismax > max){
			max = thismax;
		}else if(thismax < 0){
			thismax = 0;
		}
	}
	return max;
}

/**
	*最小子序列和
	*n
	*/
int subMinSum(int a[], int length){
	int thismin = 0, min = INT_MAX;
	for(int i=0; i<length; i++){
		thismin += a[i];
		if(thismin < min){
			min = thismin;
		}else if(thismin > 0){
			thismin = 0;
		}
	}
	return min;
}

struct Node  
{  
    int sum;  
    int xiabiao;  
      
};  
int cmp(const Node& t1,const Node& t2)  
{  
    return t1.sum < t2.sum;
} 

/**
	*最小正子序列和
	*n*logn
	*/
int positiveSubMinSum(int *data, int len){
	Node* temp = new Node[len];  
  temp[0].sum = data[0];  
  temp[0].xiabiao = 0;  
  for(int i=1;i<len;i++)  
  {  
    temp[i].sum = temp[i-1].sum+data[i];  
    temp[i].xiabiao = i;  
  }  
  //对temp.sum[]进行从小到大排序,sum[]中只有相邻的两个数才有可能 得到 最小正子序列和  
  sort(temp,temp+len,cmp);  
  int sum = INT_MAX;  
  for(int i=0;i<len-1;i++)  
  {  
    if(temp[i].xiabiao < temp[i+1].xiabiao)  
    {  
         if(temp[i+1].sum - temp[i].sum > 0 && temp[i+1].sum - temp[i].sum < sum)  
         sum = temp[i+1].sum - temp[i].sum;  
    }  
  }  
  delete temp;  
  temp=0;  
  return sum;  
}

void swap(int& a, int& b){
	 int temp = a;
	 a = b;
	 b = temp;
}

/**
	*最大子序列乘积(同时也求出了最小的子序列乘积)
	*在找最大的值得时候,必须记录最小值,因为有负数存在,最小的数可能变成最大的数
	*/
int mutiSubMax(int *a, int length){
	  int i;
    int maxProduct = 1;
    int minProduct = 1;
    int maxCurrent = 1;
    int minCurrent = 1;

    for( i=0; i<length ;i++)
    {
        maxCurrent *= a[i];
        minCurrent *= a[i];
        if(maxCurrent > maxProduct) 
            maxProduct = maxCurrent;
        if(minCurrent > maxProduct)
            maxProduct = minCurrent;
        if(maxCurrent < minProduct)
            minProduct = maxCurrent;
        if(minCurrent < minProduct)
            minProduct = minCurrent;
        //注意交换
        if(minCurrent > maxCurrent)
            swap(maxCurrent,minCurrent);
        //这个必须在最后(防止为0的时候)
        if(maxCurrent<1)
            maxCurrent = 1;
        //if(minCurrent>1)//这里不需要,因为通过交换即可,只需要一个
        //  minCurrent =1;
    }
    return maxProduct;
}

int main(){
	int a[LEN] = {4,-1,5,-2,-1,2,6,-2,1,-3};
	cout<<"列表:"<<endl;
	for(int i=0; i<10; i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	cout<<"最大子序列和:"<<subMaxSum(a, LEN)<<endl;
	cout<<"最小子序列和:"<<subMinSum(a, LEN)<<endl;
	cout<<"最小正子序列和:"<<positiveSubMinSum(a, LEN)<<endl;
	cout<<"最大子序列乘积:"<<mutiSubMax(a, LEN)<<endl;
	return 0;
}</span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值