1. 程式人生 > >陣列中連續子序列的最大和及子串(js實現)

陣列中連續子序列的最大和及子串(js實現)

<script>

var array=[1, -2, 3, 10, -4, 7, 2, -5];  //結果為3, 10, -4, 7, 2
alert(findSubArray(array).join(","));


function findSubArray(array){

if(array.length==0){
    result[0]="陣列為空!";
    return result ;
}

var result=[];//返回結果

//特殊情況處理
var firstPositiveNumIndex=-1;
var i=-1;
while(i<array.length&&array[++i]<=0){;}
//i此時表示第一個>0的數的指標或者=array.length
if(i==array.length){
//說明陣列中沒有正數,那隻需求出陣列中的最小值
    result[0]=array[0];
    for(var j=1;j<array.length;j++){
        if(array[j]>result[0]){
            result[0]=array[j];
        }else{
        //
        }
    }
    return result;
}else{
    firstPositiveNumIndex=i;
}
//下面處理一般情況,首先對陣列分段,轉換為標準形式+,-,+,-....+;

var arrayA=[];
var signal=1;
var segIndex;//段指標
var segSum;
for(var k=firstPositiveNumIndex,segIndex=0;k<array.length;){
    arrayA[segIndex]={};
    arrayA[segIndex].segSum=0;
    arrayA[segIndex].startIndex=k;//段起點在原陣列中的指標
    arrayA[segIndex].len=0;
    while(k<array.length&&signal*array[k]>=0){
        arrayA[segIndex].segSum+=array[k];
        arrayA[segIndex].len++;
        k++;
    }
    segIndex++;
    signal*=-1;//改變符號
}
//去掉arrayA後面的負數部分,由於前面已經處理過沒有正數的情況,所有下面處理後的arrayA不空
while(arrayA.length>0){
    if(arrayA[arrayA.length-1].segSum<=0){
        arrayA.pop();
    }else{
        break;
    }
}

/*
alert(arrayA.length);
for(var i=0;i<array.length;i++){
    alert(arrayA[i].len);
}
*/
var max_startIndex=-1,
    max_len=0,
    max_sum=0;  //已遍歷出的最大的連續段資訊(段起始下標,段長度,段值)

var current_startIndex=-1,
    current_len=0,
    current_sum=0;//當前遍歷中的段的跟蹤資訊(段起始下標,段長度,段值)
    

//遍歷指標指向陣列開始位置
current_startIndex=0;
var i=0;
signal=1;
do{//遍歷以arrayA[i]開始的所有可能為結果的連續序列,並統計最大值
    if(signal==1){
    //如果當前處理的是正數,計算這段的值,並與歷史資料比較
        current_sum+=arrayA[i].segSum;
        current_len++;
        //alert(i);
        //alert(current_sum);
        if(current_sum>max_sum){
            max_sum=current_sum;
            max_startIndex=current_startIndex;
            max_len=current_len;            
        }else{
            //
        }
        
    }else if(current_sum+arrayA[i].segSum>0){
        current_sum+=arrayA[i].segSum;
        current_len++;
    }else {//遇到了一個分離陣列前後部分的數,即結果值不可能包含這個元素;改變序列起點        
        current_len=0;
        current_sum=0;
        current_startIndex=i+1;
        //alert(true);
    }
    i++;
    signal*=-1;
}while(i<arrayA.length);

var resultLen=0;

for(var i=max_startIndex;i<max_startIndex+max_len;i++){
    resultLen+=arrayA[i].len;
}
//alert(resultLen);
var startInSource=arrayA[max_startIndex].startIndex;
var endInSource=startInSource+resultLen-1;
result[0]="最大值為:"+max_sum;
for(var i=startInSource;i<=endInSource;i++){
    result.push(array[i]);
}

return result;

}
</script>