求两个字符串的最长公共子序列 合工大 程序设计艺术实验四

本文主要是介绍求两个字符串的最长公共子序列 合工大 程序设计艺术实验四,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

求两个字符串的最长公共子序列.
X的一个子序列是相应于X下标序列{1, 2, …, m}的一个子序列,求解两个序列的所有子序列中长度最大的,例如输入:pear,peach输出pea.

首先你要明白什么是最长公共子序列,例如 asd5gd 和 s5666d 的最长公共子序列为s5d

在两个字符串中,有些字符会一样,可以形成的子序列也有可能相等,因此,长度最长的相等子序列便是两者间的最长公共字序列,其长度可以使用动态规划来求。

以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。

借用《算法导论》中的推导图:

创建 DP数组C[][];

在这里插入图片描述

图中的空白格子需要填上相应的数字(这个数字就是c[i][j]的定义,记录的LCS的长度值)。填的规则依据递归公式,简单来说:如果横竖(i,j)对应的两个元素相等,该格子的值 = c[i-1,j-1] + 1。如果不等,取c[i-1,j] 和 c[i,j-1]的最大值。首先初始化该表:

在这里插入图片描述

      然后,一行一行地从上往下填:

在这里插入图片描述

      S1的元素3 与 S2的元素3 相等,所以 c[2,1] = c[1,0] + 1。继续填充:

在这里插入图片描述

        S1的元素3 与 S2的元素5 不等,c[2,2] =max(c[1,2],c[2,1]),图中c[1,2] 和 c[2,1] 背景色为浅黄色。继续填充:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

           中间几行填写规则不变,直接跳到最后一行:

在这里插入图片描述
至此,该表填完。根据性质,c[8,9] = S1 和 S2 的 LCS的长度,即为5。

为了打印路径,所以在代码里增添了一个新的数组用来记录路径.
在这里插入图片描述


#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAXLEN 100using namespace std;void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{int i, j;for(i = 0; i <= m; i++)c[i][0] = 0;for(j = 1; j <= n; j++)c[0][j] = 0;                for(i = 1; i<= m; i++){for(j = 1; j <= n; j++){if(x[i-1] == y[j-1]){c[i][j] = c[i-1][j-1] + 1;b[i][j] = 0;}else if(c[i-1][j] >= c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 1;}else{c[i][j] = c[i][j-1];b[i][j] = -1;}}}
}void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{if(i == 0 || j == 0)return;if(b[i][j] == 0){PrintLCS(b, x, i-1, j-1);printf("%c ", x[i-1]);}else if(b[i][j] == 1)PrintLCS(b, x, i-1, j);elsePrintLCS(b, x, i, j-1);
}int main(int argc, char **argv)
{char x[MAXLEN];char y[MAXLEN];int b[MAXLEN][MAXLEN];int c[MAXLEN][MAXLEN];int m, n;cout << "请输入两个字符串:" << endl;scanf("%s", x);scanf("%s", y);m = strlen(x);n = strlen(y);LCSLength(x, y, m, n, c, b);cout  << "两个字符串的最大公共子序列是:" ;PrintLCS(b, x, m, n);return 0;
}

参考博客:https://blog.csdn.net/someone_and_anyone/article/details/81044153?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159110780919725247601128%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159110780919725247601128&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-81044153.first_rank_ecpm_v3_pc_rank_v3&utm_term=%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97

这篇关于求两个字符串的最长公共子序列 合工大 程序设计艺术实验四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/843861

相关文章

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

C#从XmlDocument提取完整字符串的方法

《C#从XmlDocument提取完整字符串的方法》文章介绍了两种生成格式化XML字符串的方法,方法一使用`XmlDocument`的`OuterXml`属性,但输出的XML字符串不带格式,可读性差,... 方法1:通过XMLDocument的OuterXml属性,见XmlDocument类该方法获得的xm

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu