1. 程式人生 > >求一個數組的和最大的連續子陣列及擴充套件

求一個數組的和最大的連續子陣列及擴充套件


在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);