最长公共子序列(存在多个解的情况)

  👉引言💎

在这里插入图片描述

铭记于心
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉

LCS_PLUS(存在多个解的情况)

💎关于LCS

前面我们已经详细进行讲述了关于LCS的问题,但有意思的是,前面我们都只是输出满足LCS的一个序列,但是现实问题总是复杂多变的,不可避免的的是两个字符串中的LCS很有可能不是唯一的,那么如果要求我们按字典序依次输出所有的LCS,我们又该怎么去做呢?
不妨先思考一下,再往下看吧!

其实我们只需要回顾之前打表的时候,当b[i-1][j] 等于b[i][j-1]时便是有重复解的情况,此时长度表记录哪个都可以,但是回溯路径时两边便都要走。

代码如下

for (int i = 1; i <= len1; i++) {
		for (int j = 1; j <= len2; j++) {
			if (s1[i - 1] == s2[j - 1]) { //注:此处的s1与s2序列是从s1[0]与s2[0]开始的
				c[i][j] = c[i - 1][j - 1] + 1;
				b[i][j] = 1;//给每种情况打标记,后面方便输入路径
			}
			else { //c[i][j] = max(c[i][j-1], c[i-1][j])
				if (c[i][j - 1] > c[i - 1][j]) {
					c[i][j] = c[i][j - 1];
					b[i][j] = 2; //第二种情况
				}
				else  if (c[i][j - 1] < c[i - 1][j]) {
					c[i][j] = c[i - 1][j];
					b[i][j] = 3; //第三种情况
				}
				else if (c[i][j - 1] == c[i - 1][j]) {
					c[i][j] = c[i - 1][j];//第四种情况,回溯时两边都要走
					b[i][j] = 4;
				}
			}
		}
	}
  • 整体看起来,虽然上面的打表结构并没有很大的变化,但是给 方向数组b 赋了一个 两边都回溯的情况(b[i][j]=4)却是很关键
void FindPath(int i, int j, string& text1, string& text2, string path) {
	if (i == 0 || j == 0) {
		reverse(path.begin(), path.end());
		ASN.insert(path);
		return;
	}//这里不同了,记得上面传参传长度哦
	if (b[i][j] == 1) {
		path += text1[i - 1];
		FindPath(i - 1, j - 1, text1, text2, path);
	}
	else if (b[i][j] == 2)
	{
		FindPath(i, j - 1, text1, text2, path);
	}
	else if (b[i][j] == 3)
	{
		FindPath(i - 1, j, text1, text2, path);
	}
	else if (b[i][j] == 4) {//两边都走
		FindPath(i - 1, j, text1, text2, path);
		FindPath(i, j - 1, text1, text2, path);
	}
}

所以这里主要更改的就是 记录路径时 遇到 长度相同的情况(存在重复解)时 两边都走一边

💎最长公共子串

  • 那么最长公共子串的多个解情况呢?

其实这个是在上面最长公共子序列路径多解的情况下比较直观可以看出的,我们只要在打好的表中找到所有长度等于最大值的对应下标,然后依次回溯相应的长度,就可以得到每一个符合条件的字符串,然后找其中最优的解就好啦!

相信现在的你对这系列问题已经 深有感悟了吧!
看,这就是算法的奥妙

🌹写在最后💖
路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹在这里插入图片描述


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想new的出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值