LCS-最长子序列问题-C实现

25 篇文章 2 订阅

最长子序列问题分析及求解实例

最长子序列问题(Longest Common Subsequence),即求解两序列的最长子序列或其长度。


EX:有两序列

A:LolitaIsHisSin
B:LolitaIsHisLight

显而易见,“LolitaIsHis”即是A和B的最长子序列,其长度为11.


求解最长公共子序列长度 LongestLength 这样的问题,我们有以下思路:
1、从头开始比对,遇到相同项即让记录的最大长度加1
2、若两项不相同,则看序列中的下一项
3、如此比对直到比对完两个序列中所有的项


上代码

—LCM迭代法实现 —


/* Find the Length of Longest Common Subsequence -- sotre res in note */
/* note is used to store the length */
void LCM(string stringA,string stringB,int note[sizex][sizex])
{
    for(int ptrA =0;ptrA<=stringA.length();ptrA++){
        for(int ptrB = 0;ptrB<=stringB.length();ptrB++){
            if(ptrA==0||ptrB==0)
                note[ptrA][ptrB]= 0;
            else if(stringA[ptrA] == stringB[ptrB] ){
                /* Longest Length Add 1 */
                note[ptrA][ptrB]= note[ptrA-1][ptrB-1]+1;
            }else {
                /* choose the bigger in upwards and left -- using ?-expression */
                note[ptrA][ptrB] = note[ptrA-1][ptrB]>note[ptrA][ptrB-1]
                ?
                note[ptrA-1][ptrB]:note[ptrA][ptrB-1];
            }
        }
    }
    
    /* show the result */
    DisPlayArray(note);
}

—LCM迭代法实现 —



调用函数DisPlayArray();

/* DisPlay The result Array */
void DisPlayArray(int note[sizex][sizex])
{
    for(int ptra = 0;ptra<sizex;ptra++)
        for(int ptrb = 0;ptrb<sizex;ptrb++){
        if(ptrb == sizex-1)
            /* end of the line: note[num][end] --> '\n' */
            cout<<endl;
        else
            cout<<note[ptra][ptrb]<<" ";
    }
}


主函数

int main()
{
    int note[sizex][sizex] = {0};
    /* compare the two str --  "1234FIRST5678" and "1234SECOND5678" */
    LCM("1234FIRST5678","1234SECOND5678",note);
    return 0;
}

执行结果


可以看到,从第一项比较到最后一项得出的最大子序列长度为9 —— 12345678和S,符合预期。



值得注意的是,第二步引发了一个问题,让我们不倾向于选择使用递归的方法求解这个问题:

对于序列
C: didactical
D: advantage
比对到第三项时,我们可以选择先看C的下一项,或者D的下一项.
而两种选择都引发了后续的类似的问题---都会引发先看哪一个序列的问题

事实上,问题并不在于先看哪一个序列,因为两个序列的所有项都会被逐一比较。问题在于每次选择都引发了后续的类似选择,导致有些比较的情况被重复进行,浪费了时间。

用一张图来看看上面所说的“重复”出现在哪儿:
在这里插入图片描述
可以看到,不同的选择可能会引发相同的比较情况,故而使用递归的方法求解这个问题是不够理想的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值