数组中连续子序列的最大和及子串(js实现)

来源:互联网 发布:鹅绒比鸭绒暖和吗 知乎 编辑:程序博客网 时间:2024/06/15 03:51
<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>
原创粉丝点击