最长公共子串

POJ1458……

http://acm.pku.edu.cn/JudgeOnline/problem?id=1458

 

算法思想如下:

 

设,A={a1,a2,a3...ax}和B={b1,b2,b3...by}是两串,B'={bi,bj...bk};且B'是串B的子集,B'串是a串的子串。则,B'中每个元素必出现在A串中,即,对某bi有bi==aj(i<=x&&j<=y)。且,A中与B'中对应的元素出现的先后顺序与之在B'中出现的先后顺序相同。也就是说,B'中的每一个元素均出现在A中,且在A中出现的先后顺序与其在B'中出现的先后顺序相同。

这样,就可以先把A中的每个元素出现的位置保存起来。因为A中可能存在重复的元素,所以使用了二维数行代表每个字母,列中的数字是其在串A中出现的位置。对某一字母在A中出现的位置,用链表连接起来,表头是A【0】,其值是当前字母在A中出现的第一个位置。若A[0]==0,则表示该字母不出现于A中。

读入B。对B中的每个字母,查看其是否出现在A中。若出现,则取其第一次在A中出现的位置,与B中前一个出现在A中的字母的位置i相比,判断其位置是否合法(该位置在i之后);若合法,则说明其是A,B的公共字串。否则,应该在关于A的二维数组中去掉当前字母的位置i(因为其非法i后可能还有其他位置)。

 

代码:

 

 

该算法是线性算法。时间复杂度为O(m+n)。程序要做的是读入两个串并对其线性处理。处理过程中不需要回溯等。

比较初级的算法是利用回溯的算法。http://blog.csdn.net/jqandjq/archive/2009/03/24/4021302.aspx时间复杂度应该是O(m*n)

 

有类似的题目,如:最大子序列和等。如下:

 

 

这是清华的一道复试题。曾经在weiss的书上看到过,当时列出了4个算法,第三个是个递归。这个号称完美的线性联机算法。原来死活看不懂……其实想想也很简单,依照上面的方法可以很容易证明其正确性。

补一句:weiss书上约定,若和为负数,则最大和为0;我这里去掉了改限制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值