前言
这篇博客不是偏向讲解型的,网上图文详细的算法相关的文章有很多,比我写的好的有更多,我写这个只是想在学习完后有个记录,方便日后如果忘记了,可以通过博客快速回忆。
最长公共子串
介绍
子串和子序列的区别,一言以蔽之,子串是连续的,子序列可以是不连续的,这里我借用别人的图来介绍一下
而最长公共子串,就是要找到两条字符串中最长的相等子串
实现原理
1.暴力算法
暴力算法解决这个问题,大致思想就是在第一条字符串中依次去除所有可能子串,然后与第二条进行比较,查看有无相同子串。这个方法优点在于好想好写,但是时间复杂度超过O(n^2),即使优化也是超过 的,跑OJ也是跑步过去的,顾舍弃。
2.动态规划
动态规划是将之前的结果存储起来,供后面的情况使用,这里用状态转换方程解释一下
直接看状态转换方程可能看不懂,这里设想一下 有两条字符串 str1,str2
如果str1[i]==str2[j], 而它两的下一项又相等 即str1[i+1]==str2[j+1],
那么此时子串的长度是不是要在原来的基础上+1 即C[i+1,j+1]=C[i,j]+1
为了表示方便,将上式写成 C[i,j]=C[i-1,j-1]。
可能有人要问了:“如果str1[i]!=str2[j],那是什么过程呢?”
这里我们要先对表进行初始化,将所有位置初始化为0,这样,如果str1[i]!=str2[j],不执行上面的+1操作,该位置为0,这样如果下面的两个位置相等,则有从1开始计数
代码展示
/*
两个字符串
和动态规划需要填的表map
*/
class LongestSub
{
private:
std::string str1;
std::string str2;
/*std::vector<std::vector<int>> vec;*/
int **map;
}
void LongestSub::iniString()
{
/*
初始化两个字符串
和表map
*/
std::ifstream fin("data.txt");
getline(fin,this->str1);
getline