10066双塔

来源:互联网 发布:有些源码上传会失败 编辑:程序博客网 时间:2024/05/24 00:36

双塔问题实际上就是在两个字符串中寻找最大公共子字符串。

借由双塔问题来具体理解分析一下最大公共子字符串问题。


本文包含以下内容

1.数学模型的建立

2.递推伪代码

3.具体程序


1.数学模型的建立

我们可以想象有两根指针i、j,分别指向数组a,数组b的起始位置。

如果当前两根指针指向的字符是相同的,我们可以把两根指针同时向后移动一位,同时公共子字符串的数目增加1.

如果两根指针指向的字符是不同的,我们可以考虑移动i或者j.


现在定义状态(i,j)表示截止到a[i]、b[j]

d[i][j] 表示 截止到a[i]、b[j]时最大公共子字符串长度,考虑状态转移过程

d[i][j]可能是由三种状态转移得来的,即d[i-1][j-1],d[i-1][j],d[i][j-1].  根据d[i][j]的含义,我们可得状态转移方程:

if(a[i-1] == b[j-1] )  d[i][j] = d[i-1][j-1]+1;

else    d[i][j] = max{d[i-1][j],d[i][j-1]}


2.递推伪代码

一问:我们最终要求的结果是谁

    答:d[len1][lenb]  len1为a的元素个数,len2位b的元素个数


二问:起始状态有哪些?

   答:已知d[0][0] = 0;d[0][0->len2]=0;d[0->len1][0] = 0;

          接下来计算

          d[1][1],d[1][2],d[1][3]....d[1][len]

          d[2][1]...........................d[2][len]


         因此i是第一层循环且i:1->len1

                j是第二层循环且j:1->len2


综上,递推形式的位代码为:

      d[0][0->len2]=0;d[0->len1][0] = 0;

      for i:1->len1

         do for  j:1->len2

              if(a[i-1]==b[j-1]) d[i][j] = d[i-1][j-1]+1

              else                   d[i][j] = max{d[i-1][j],d[i][j-1]}



3.具体实现代码

   

#include<iostream>using namespace std;int a[100];int b[100];int len1, len2;int main(){while (cin >> len1 >> len2){if (len1 == 0)break;for (int i = 0; i < len1; i++)cin >> a[i];for (int j = 0; j < len2; j++)cin >> b[j];int d[100][100];memset(d, 0, sizeof(d));for (int i = 1; i <= len1; i++)for (int j = 1; j <= len2; j++){if (a[i - 1] == b[j - 1]) d[i][j] = d[i - 1][j - 1] + 1;else{if (d[i - 1][j]>d[i][j - 1])d[i][j] = d[i - 1][j];elsed[i][j] = d[i][j - 1];}}cout << d[len1][len2];}return 0;}











          

0 0
原创粉丝点击