当前位置:嗨网首页>书籍在线阅读

11-伪代码详解

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.3.4 伪代码详解

(1)最长公共子序列求解函数

首先计算两个字符串的长度,然后从i=1开始,s1[0]与s2中的每一个字符比较。

如果当前字符相同,则公共子序列的长度为c[i−1][j−1]+1,并记录最优策略来源b[i][j] = 1。

如果当前字符不相同,则公共子序列的长度为c[i][j−1]和c[i−1][j]中的最大值,如果c[i][j−1]c[i−1][j],则最优策略来源b[i][j]=2;如果c[i][j−1]<c[i−1][j],则最优策略来源b[i][j]=3。直到i> len1时,算法结束,这时c[len1][len2]就是我们要的最长公共序列长度。

Void LCSL()
{
    int I,j;
    for(I = 1;I <= len1;i++)    //控制s1序列
      for(j = 1;j <= len2;j++)  //控制s2序列
      {
        if(s1[i-1]==s2[j-1])    //字符下标从0开始
        {   //如果当前字符相同,则公共子序列的长度为该字符前的最长公共序列+1
            c[i][j] = c[i-1][j-1]+1;
            b[i][j] = 1;
        }
        else
        {
            if(c[i][j-1]>=c[i-1][j]) //两者找最大值,并记录最优策略来源
            {
                  c[i][j] = c[i][j-1];
                  b[i][j] = 2;
            }
            else
            {
                  c[i][j] = c[i-1][j];
                  b[i][j] = 3;
            }
        }
     }
}

(2)最优解输出函数

输出最优解仍然使用倒推法。因为我们在求最长公共子序列长度c[i][j]的过程中,用b[i][j]记录了c[i][j]的来源,那么就可以根据b[i][j]数组倒推最优解。

如果b[i][j]=1,说明s1[i−1]=s2[j−1],那么我们就可以递归输出print(i−1,j−1);然后输出s1[i−1]。

如果b[i][j]=2,说明s1[i−1]≠s2[j−1]且最优解来源于c[i][j]=c[i][j−1],递归输出print(i,j−1)。

如果b[i][j]=3,说明s1[i−1]≠s2[j−1]且最优解来源于c[i][j]=c[i−1][j],递归输出print(i−1,j)。当i==0||j==0时,递归结束。

Void print(int I, int j)//根据记录下来的信息构造最长公共子序列(从b[i][j]开始递推)
{
    if(i==0 || j==0) return;
    if(b[i][j]==1)
    {
        print(i-1,j-1);
        cout<<s1[i-1];
    }
    else if(b[i][j]==2)
              print(I,j-1);
          else print(i-1,j);
}