图片来自https://www.jianshu.com/p/096c945be66b
注意:
1)如上图表格,字符串的第i个字符在逻辑上是c[i,j]中的i。
但是,在物理存储上存储在i-1(下标位置)
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (m_str1[i-1] == m_str2[j-1])//attention!!!
2)打印时采用回溯法,故采用栈先进后出(或者数组存放,倒序输出)
回溯的逻辑
if (在各自的当前位置处字符相同) {
字符入栈;各自回退一步;
}else if(m_comlen[l1 - 1][l2] == m_comlen[l1][l2 - 1])//两条路均可选一条
l1--;
else if(m_comlen[l1-1][l2] < m_comlen[l1][l2 - 1])//选来时的路,较大的方向
l2--;
else
l1--;
#pragma once
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
const unsigned int MAXSIZE = 101;
class Lcs
{
public:
Lcs(){
}
Lcs(string s1,string s2):m_str1(s1),m_str2(s2) {
init();
}
~Lcs(){
}
void init() {
int len1 =m_str1.size(),len2= m_str2.size();
for (int i = 0,j=0; i <=len1,j<=len2; i++,j++) {
m_comlen[i][0] = m_comlen[0][j] = 0;
}
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
if (m_str1[i-1] == m_str2[j-1])//attention!!!
m_comlen[i][j] = m_comlen[i - 1][j - 1] + 1;
else {
m_comlen[i][j] =
max(m_comlen[i - 1][j],
m_comlen[i][j - 1]);
}
}
}
/*
for (int i = 0; i <= len1; i++) {
for (int j =0; j <= len2; j++) {
cout << m_comlen[i][j] << " ";
}
cout << endl;
}
*/
}
void getLCS() {
int l1 = m_str1.size(), l2 = m_str2.size();
stack<char> s;
while (m_comlen[l1][l2]) {
if (m_str1[l1-1] == m_str2[l2-1]) {
s.push(m_str2[l2-1]);
l1--;
l2--;
}else if (m_comlen[l1 - 1][l2] == m_comlen[l1][l2 - 1])
l1--;
else if (m_comlen[l1-1][l2] < m_comlen[l1][l2 - 1])
l2--;
else
l1--;
}
while (!s.empty()) {
cout << s.top(); s.pop();
}
cout << endl;
}
private:
string m_str1,m_str2;
int m_comlen[MAXSIZE][MAXSIZE];
};
void testLcs() {
string s1 = "ihaveapple", s2 = "ihasapp";
Lcs test(s1, s2);
test.getLCS();
}