求一个数组的和最大的连续子数组及扩展


在C++中a=1与a(1)有什么区别?a=1是赋值,a(1)是一个函数值

求1亿内的素数,并输出。

#include<stdio.h>
#include<math.h>
const long N = 10000001;
bool prime[10000001];
int main()
{
long i, j;
for(i=2; i<N; i++)
{
if(i%2 == 0) prime[i]=false;
else prime[i]=true;
}
prime[2]=true;
for(i=3; i<=sqrt(N); i+=2)
{   
if(prime[i])
for(j=i+i; j<N; j+=i)
prime[j]=false;
}
for(i=2; i<N; i++)//由于输出将占用太多io时间,所以只输出2-100内的素数。可以把100改为N
if( prime[i] )
printf("%d ",i);
return 0;
}

class A{
};

cout<<sizeof(A)<<endl; 1

class A{
int a;
};

cout<<sizeof(A)<<endl; 4

class A{

static int a;
};

cout<<sizeof(A)<<endl; 1

class A{
};
class B: virtual A {
cout<<sizeof(B)<<endl; 4

class A{
virtual ~A();
};
class B: virtual A {
};

cout<<sizeof(B)<<endl;8

class A{
virtual ~A();
};
class B: virtual A {

virtual ~B();
};

cout<<sizeof(B)<<endl;8

编程之美:

给定一整数数组,求连续的子数组和的最大值:

设置两个整数变量:cur 和sum,从给定数组中依次取出所有元素,加到cur 上去,当cur<0 时候重置cur。sum 记录cur 出现过的最大值:

var cur = array[0];
var sum = cur;
for (int i = 1; i < array.Length; i++)
{
cur = cur < 0 ? array[ i ] : cur + array[ i ];
if (sum < cur) sum = cur;
}
return sum;

扩展问题二解法

如果要求得到最大和的连续子数组的起始位置,那么通过以上思路就更加容易写出代码:

int start1 = 0, start2 = 0, end = 0;
var cur = array[0];
var sum = cur;
for (int i = 1; i < array.Length; i++)
{
    if (cur < 0)
    {
        cur = array[ i ];
        start2 = i;
    }
    else cur += array[ i ];
    if (sum < cur)
    {
        sum = cur;
        end = i;
        start1 = start2;
    }
}
//返回 [start1, end]

本例中,我们用start1,start2 来记录起始位置,end 来记录终止位置。start2 相当于“工作变量”,start1 保存历史最大和连续子数组的起始位置。


扩展问题一解法

如果给定的是数组是首尾相连的循环数组,如何求解?首先设计一个函数,求解给定数组中,从from 开始的,最多到to 结束的最大和连续子数组的末尾位置,思路和前面解法类似。

int MaxSum_Position(int[] array, int from, int to)
{
    int step = Math.Sign(to - from);
    int end = from;
    var cur = array[from];
    var sum = cur;
    for (int i = from + step; i != to + step; i += step)
    {
        cur += array[ i ];
        if (sum < cur)
        {
            sum = cur;
            end = i;
        }
    }
return end;
}

有了这个函数以后,可以将循环数组中的问题分成两种情况:一种是连续子数组跨越了0 位置的,一种是没有跨越的:

int sum1 = MaxSum(array);//不跨越0 位置的最大和
int i = MaxSum_Position(array, 0, array.Length - 1);
int j = MaxSum_Position(array, array.Length - 1, 0);
int sum2 = 0;
if (i > j) j = i + 1;
for (int k = 0; k < array.Length; k++)
{
sum2 += array[ k ];
if (k == i) k = j - 1; //跳过中间空缺部分
}
return Math.Max(sum1, sum2);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值