10066双塔

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

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


本文包含以下内容

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];
					else
						d[i][j] = d[i][j - 1];
				}
			}

		cout << d[len1][len2];
	}
	return 0;
}











          

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值