【算法设计-最长公共子串与最长公共子序列】

本文介绍了两个经典的动态规划问题——最长公共子串和最长公共子序列的求解方法,并通过示例代码展示了如何使用C++实现这两种算法。此外,还讨论了一个关于机器人路径规划的问题,同样采用动态规划的方法进行解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先写代码,然后晚上上传过程图

公共子串:一定要是字符串中连续的字符

公共子序列:可以不是联系的字符串

一.最长公共子串问题

#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void func(char str1[], char str2[])
{
int str1len = strlen(str1);
int str2len = strlen(str2);
vector<vector<int>>dp(str1len + 1, vector<int>(str2len + 1, 0));
int max = dp[0][0];
int tempi = 0;
int tempj = 0;
for (int i = 1; i <= str1len; i++)
{
for (int j = 1; j <= str2len; j++)
{
if (str1[i - 1] == str2[j - 1])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else
dp[i][j] = 0;
if (dp[i][j]>max)
{
max = dp[i][j];
tempi = i;
tempj = j;
}
}
}
cout << "最长子串长度是" << max << endl;
int i = tempi;
int j = tempj;
stack<char>charstack;
for (; dp[i][j] != 0; --i, --j)charstack.push(str1[i]);
cout << "最长公共字符串是";
while (!charstack.empty())
{
cout << charstack.top();
charstack.pop();
}
cout << endl;
}
int main(void)
{
char a[] = "edkf";
char b[] = "dk";
func(a, b);
}

二.最长公共子序列问题

#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int LongestSubStr(char *str1, char *str2)
{
int i, j;
int maxi, maxj;
int n = strlen(str1);
int m = strlen(str2);
vector<vector<int>> c(n+1,vector<int>(m+1, 0));
int max = -1;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
if (str1[i - 1] == str2[j - 1])
c[i][j] = c[i - 1][j - 1] + 1;
else c[i][j] = (c[i - 1][j] > c[i][j - 1]) ? c[i - 1][j] : c[i][j - 1];
if (c[i][j] >= max)
max = c[i][j];
}
}
printf("最长子序列长度是%d", max);
stack<char>a;
for (i = n, j = m; i >= 1 && j >= 1;)
{
if (str1[i - 1] == str2[j - 1])
{
a.push(str1[i - 1]);
i--;
j--;
}
else
{
if (c[i - 1][j] > c[i][j - 1])
i--;
else
j--;
}
}
cout << "子序列是:";
while (!a.empty())
{
char temp = a.top();
cout << temp;
a.pop();
}
cout << endl;
return max;
}
int main(void)
{
int max;
char a[100] = "feilong44";
char b[100] = "flng5";
max = LongestSubStr(a, b);
return 0;
}

第三题

给定一格M*N的地图,有个机器人放在左上角的格子里面,它要走到地图的右下角,这个机器人每次只能向下或者向右移动一格,当它移动到右下角时表示结束。求:有多少条不同的路径可以到达右下角?

方法:

动态规划

m==0或者n==0时候的值要设置为1,即第一行和第一列的值都要设置为1.dp[i][j]=dp[i][j-1]+dp[j][i-1];

即每个格子的值为他的上面和左边的数值的和。

代码:

#include<iostream>
#include<vector>
using namespace std;
int func(int m, int n)
{
vector<vector<int>>a(m, vector<int>(n,1));
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
a[i][j] = a[i][j - 1] + a[i - 1][j];
}
return a[m - 1][n - 1];
}
int main(void)
{

int temp=func(3, 4);
cout << temp << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值