照旧,先上下我的暴力破解法:
#include <iostream> #include <string> #include <algorithm> using namespace std; string ToLower(string ss) { string::iterator itr; for(itr=ss.begin();itr!=ss.end();itr++) { *itr=tolower(*itr); } return ss; } int getCommonStrLength(string pFirstStr,string pSecondStr) { int firstLen=pFirstStr.length(); int secondLen=pSecondStr.length(); int countMax=0; for(int f=0;f<firstLen;f++) { int fCurrent=f; for(int s=0;s<secondLen;s++) { int tempCount=0; int sCurrent=s; while(sCurrent<secondLen&&fCurrent<firstLen&&pFirstStr[fCurrent]==pSecondStr[sCurrent]) { ++tempCount; ++fCurrent; ++sCurrent; } if(tempCount>countMax) countMax=tempCount; } } return countMax; } int main() { string fStr; string sStr; cin>>fStr>>sStr; fStr=ToLower(fStr); sStr=ToLower(sStr); cout<<getCommonStrLength(fStr,sStr)<<endl; }
两个for循环是必须的,但是第二层的for循环内的while就明显是进行了很多重复的操作比较。得改!那就是要记录之前做过的记录,考虑用动态规划思想进行。
其实我开始的时候打算用后缀数组进行比较,但没思路。就没进行下去了。最后,在网上搜了下,有一种思路是利用前缀数组进行LCS算法。用一个二维数组Sub[firstLen][SecondLen]记录公共字符串,即Sub[m][n]记录的是第一个字符串第m位开始于第二个字符串第n位开始具有的公共字符串。那么,在比较Sub[m+1][n+1]时,我们只需要判断FirstStr[m+1],SecondStr[n+1]即可,如果他们相同,那么就可以利用之前Sub[m][n]的记录,因为第一个字符串从m+1往前,m位以前的之前已经比较过了;同理,第二个字符串从n+1开始,n位之前的已经比较过了,所以Sub[m+1][n+1]=Sub[m][n]+FirstStr[m+1]。
代码:
http://blog.csdn.net/liufeng_king/article/details/8528858
// CPPPRO.cpp : 定义控制台应用程序的入口点。 //3m6 最长公共子串,动态规划实现 #include "stdafx.h" #include <iostream> #include <string> using namespace std; string getLCSLength(string &s, string &t); int main() { string s,t; cout<<"请输入字符串s:"<<endl; cin>>s; cout<<"请输入字符串t:"<<endl; cin>>t; cout<<"最长公共子串为:"<<endl; cout<<getLCSLength(s,t)<<endl; return 0; } string getLCSLength(string &s, string &t) { int p = s.length(); int q = t.length(); string **num = new string *[p]; for(int i=0;i<p;i++) { num[i] = new string[q]; } char char1 = '