最长公共子串和最长公共子序列在状态转移方程有些类似的地方,不同的是长公共子串要求必须在原串中是连续的,所以一但某处出现不匹配的情况,此处的值就重置为0。
下面给出最长公共子串的状态转移方程:
- dp[0][j] = 0; (0<=j<=m)
- dp[i][0] = 0; (0<=i<=n)
- dp[i][j] = dp[i-1][j-1] +1; (str1[i] == str2[j])
- dp[i][j] = 0; (str1[i] != str2[j])
不多说上代码---实现了打印最长公共子串的功能,很简单!
#include "stdafx.h" #include <stdio.h> #include <string> #include <iostream> using namespace std; #define MAXSIZE 100 char str1[MAXSIZE]; char str2[MAXSIZE]; int dp[MAXSIZE][MAXSIZE]; //'y'代表str1[i] = str2[j];'n'反之 char path[MAXSIZE][MAXSIZE]; void printComStr(int i, int j) { if (path[i][j] == 'n' || i == 0 || j == 0) return; if (path[i][j] == 'y') { printComStr(i - 1, j - 1); cout << str1[i - 1]; } } int main() { int n, m; int indexi, indexj; int ans = 0; cin >> str1 >> str2; n = strlen(str1); m = strlen(str2); for (int i = 0; i <= n;i++) for (int j = 0; j <= m; j++) { dp[i][j] = 0; } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (str1[i - 1] == str2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; path[i][j] = 'y'; } else { dp[i][j] = 0; path[i][j] = 'n'; } } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (ans < dp[i][j]) { ans = dp[i][j]; indexi = i; indexj = j; } } cout << ans << endl; cout << indexi << ' ' << indexj << endl; printComStr(indexi, indexj); }
写代码是一种艺术,甚于蒙娜丽莎的微笑。