js算法:动态规划-最大公共子串与最大子段和

最大公共子串代码:


        问题定义:比如输入两个字符串BDCABA和ABCBDAB的最长公共字符串有BD和AB,它们的长度都是2

       动态规划思路:假设两个字符串分别为s和t,s[i]t[j]分别表示其第i和第j个字符(字符顺序从0开始),再令L[i, j]表示以s[i]t[j]为结尾的相同子串的最大长度。应该不难递推出L[i, j]L[i+1,j+1]之间的关系,因为两者其实只差s[i+1]t[j+1]这一对字符。若s[i+1]t[j+1]不同,那么L[i+1, j+1]自然应该是0,因为任何以它们为结尾的子串都不可能完全相同;而如果s[i+1]t[j+1]相同,那么就只要在以s[i]t[j]结尾的最长相同子串之后分别添上这两个字符即可,这样就可以让长度增加一位。合并上述两种情况,也就得到L[i+1,j+1]=(s[i]==t[j]?L[i,j]+1:0)这样的关系。

最后就是要小心的就是临界位置:如若两个字符串中任何一个是空串,那么最长公共子串的长度只能是0;当i0时,L[0,j]应该是等于L[-1,j-1]再加上s[0]t[j]提供的值,但L[-1,j-1]本是无效,但可以视s[-1]是空字符也就变成了前面一种临界情况,这样就可知L[-1,j-1]==0,所以L[0,j]=(s[0]==t[j]?1:0)。对于j0也是一样的,同样可得L[i,0]=(s[i]==t[0]?1:0)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> 最大长度公共子串 </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <script>
    var str1="abcdefghijklname123what";
	var str2="defghiwhatisyourname";
    var L=[];//备忘录 记录L[i][j]最大长度子串L[i][j]=max(L[i-1][j-1]+1,0)
	getMaxSubStr();
    function getMaxSubStr(){
	   for (var i=0;i<str1.length+1;i++)
	   {
	     L[i]=[];
		 L[i][0]=0;
	   }
	   for (var j=0;j<str2.length+1;j++ )
	   { 
	     L[0][j]=0;
	   }
	   var max=-1;
	   var x=-1;
	   var y=-1;
	   for (var i=1;i<str1.length+1;i++ )
	   {
	      for (var j=1;j<str2.length+1;j++ )
		  {
		     //alert(str1[i-1]+":"+str2[j-1]);
		     if(str1.charAt(i-1)==str2.charAt(j-1)){
			    L[i][j]=L[i-1][j-1]+1;
			 }
			 else{
			    L[i][j]=0;
			 }
			 
			 //document.write(L[i][j]);
			 if(L[i][j]>max){
			    max=L[i][j];
				x=i-1;
				y=j-1;
				document.write("i="+i+";j="+j+";max="+max+"<br/>");
			 }
		  }
	   }
       //输出共同的子串
	   var str=[];
	   while(x>=0&&y>=0){
	      if(str1.charAt(x)==str2.charAt(y)){
		     str[--max]=str1.charAt(x);
			 x--;
			 y--;
		  }
		  else
		     break;
	   }
	   var str_out="";
	   for (var i=0;i<str.length;i++ )
	   {
	     str_out+=str[i];
	   }
	   document.write(str_out);
	}
	
  </script>
 </HEAD>

 <BODY>
  
 </BODY>
</HTML>


最大子段和:

问题定义:对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。


动态规划算法求解:

    算法思路如下:

    记,则所求的最大子段和为:

    由b[j]的定义知,当b[j-1]>0时,b[j]=b[j-1]+a[j],否则b[j]=a[j]。由此可得b[j]的动态规划递推式如下:

     b[j]=max{b[j-1]+a[j],a[j]},1<=j<=n。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <script>
    var array=[-5 ,-6 ,-1 ,-5 ,-4 ,-7];
    var b=0;  
    var sum=0;  
    for(var i=0;i<array.length;i++)  
    {  
        if(b>0)  
        {  
            b+=array[i]; 
			document.write(b+";"+array[i]+"<br/>");
        }  
        else  
        {  
            b=array[i];  
        }  
        if(b>sum)  
        {  
            sum=b;  
			document.write("sum:"+sum+"<br/>");
        }  
    }  
    document.write(sum);
	</script>
 </HEAD>

 <BODY>
  
 </BODY>
</HTML>


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值