#include<iostream>
#include<limits>
#include<vector>
#include<stack>
#include<string>
#define LEFTUP 0
#define LEFT 1
#define UP 2
using namespace std;
//最大子串
int maxSubSum(const vector<int> & arr,int &begin,int &end) {
int maxSum = numeric_limits<int>::min();
int curSum = 0;
int newbegin = 0;
for(int i = 0; i<arr.size(); i++) {
curSum += arr[i];
if(curSum > maxSum) {
maxSum = curSum;
begin = newbegin;
end = i;
}
if(curSum < 0) {
curSum = 0;
newbegin = i+1;
}
}
return maxSum;
}
void test_maxSubSum() {
int len;
cout<<"输入数组长度:"<<endl;
cin>>len;
cout<<"输入数组内容:"<<endl;
vector<int> arr;
int a;
for(int i = 0; i<len; i++) {
cin>>a;
arr.push_back(a);
}
int begin,end;
cout<<maxSubSum(arr,begin,end)<<endl;
for(int i = begin ; i<=end; i++)
cout<<arr[i]<<" ";
cout<<endl;
}
//最长递增子序列 :动态规划的思想
void test_maxIncSeq() {
const int len=14;
int arr[len]= {1,9,3,8,11,4,5,6,4,1,9,7,1,7};
vector<int> vec(&arr[0],&arr[len]);
vector<int> monoseqlen(len,1); //以每个元素结尾的最长递增子序列的长度
vector<int> preindex(len,-1); //以每个元素结尾的最长递增子序列的上一个节点位置
int maxmonoseqlen=-1;
int maxmonoindex=-1;
for(int i=1; i<len; ++i) {
int curr=vec[i];
for(int j=0; j<i; ++j) {
if(vec[j]<vec[i]) {
int msl=monoseqlen[j]+1;
if(msl>monoseqlen[i]) {
monoseqlen[i]=msl;
preindex[i]=j;
}
}
}
}
for(int i=0; i<len; ++i) { //遍历一次,找到最长递增子序列的长度
if(monoseqlen[i]>maxmonoseqlen) {
maxmonoseqlen=monoseqlen[i];
maxmonoindex=i;
}
}
stack<int> st; //保存最终子序列结果
while(maxmonoindex>=0) {
st.push(vec[maxmonoindex]);
maxmonoindex=preindex[maxmonoindex];
}
vector<int> rect;
while(!st.empty()) {
rect.push_back(st.top());
st.pop();
}
vector<int>::iterator itr=rect.begin();
while(itr!=rect.end()) {
cout<<*itr++<<"\t";
}
cout<<endl;
}
//最长公共子串LCS
const string LCS(const string& str1,const string& str2) {
int xlen=str1.size(); //横向长度
vector<int> tmp(xlen); //保存矩阵的上一行
vector<int> arr(tmp); //当前行
int ylen=str2.size(); //纵向长度
int maxele=0; //矩阵元素中的最大值
int pos=0; //矩阵元素最大值出现在第几列
for(int i=0; i<ylen; i++) {
string s=str2.substr(i,1);
arr.assign(xlen,0); //数组清零
for(int j=0; j<xlen; j++) {
if(str1.compare(j,1,s)==0) { //int compare (size_t pos, size_t len, const string& str) 相同返回0 不同返回-1
if(j==0)
arr[j]=1;
else
arr[j]=tmp[j-1]+1; //左上方元素+1
if(arr[j]>maxele) {
maxele=arr[j];
pos=j;
}
}
}
tmp.assign(arr.begin(),arr.end());
// vector的拷贝:https://www.cnblogs.com/xiaopanlyu/p/5644666.html
//?? tmp = arr;
// template <class InputIterator> string& assign (InputIterator first, InputIterator last);
}
string res = str1.substr(pos-maxele+1,maxele);
return res;
}
void test_LCS() {
string str1("21232523311324");
string str2("312123223445");
string lcs=LCS(str1,str2);
cout<<lcs<<endl;
}
/*最长公共子序列: 符号约定,C1是S1的最右侧字符,C2是S2的最右侧字符,S1‘是从S1中去除C1的部分,S2'是从S2中去除C2的部分。
LCS(S1,S2)等于下列3项的最大者:
(1)LCS(S1,S2’)
(2)LCS(S1’,S2)
(3)LCS(S1’,S2’)--如果C1不等于C2; LCS(S1',S2')+C1--如果C1等于C2;
边界终止条件:如果S1和S2都是空串,则结果也是空串。*/
int Max(int a,int b,int c,int *max) { //找最大者时a的优先级别最高,c的最低.最大值保存在*max中
int res=0; //res记录来自于哪个单元格
*max=a;
if(b>*max) {
*max=b;
res=1;
}
if(c>*max) {
*max=c;
res=2;
}
return res;
}
string LCS_2(const string& str1,const string& str2) {
int xlen=str1.size(); //横向长度
int ylen=str2.size(); //纵向长度
if(xlen==0||ylen==0) //str1和str2中只要有一个为空,则返回空
return "";
pair<int,int> arr[ylen+1][xlen+1]; //构造pair二维数组,first记录数据,second记录来源
for(int i=0; i<=xlen; i++) //首行清0
arr[0][i].first=0;
for(int j=0; j<=ylen; j++) //首列清0
arr[j][0].first=0;
for(int i=1; i<=ylen; i++) {
char s=str2.at(i-1);
for(int j=1; j<=xlen; j++) {
int leftup=arr[i-1][j-1].first;
int left=arr[i][j-1].first;
int up=arr[i-1][j].first;
if(str1.at(j-1)==s) //C1==C2
leftup++;
int max;
arr[i][j].second=Max(leftup,left,up,&arr[i][j].first);
}
} /*矩阵构造完毕*/
//回溯找出最长公共子序列
stack<int> st;
int i=ylen,j=xlen;
while(i>=0&&j>=0) {
if(arr[i][j].second==LEFTUP) {
if(arr[i][j].first==arr[i-1][j-1].first+1)
st.push(i);
--i;
--j;
} else if(arr[i][j].second==LEFT) {
--j;
} else if(arr[i][j].second==UP) {
--i;
}
}
string res="";
while(!st.empty()) {
int index=st.top()-1;
res.append(str2.substr(index,1));
st.pop();
}
return res;
}
void test_LCS_2() {
string str1="GCCCTAGCG";
string str2="GCGCAATG";
string lcs=LCS(str1,str2);
cout<<lcs<<endl;
}
int main() {
// test_maxSubSum();
// test_maxIncSeq();
// test_LCS();
test_LCS_2();
return 0;
}
参考:https://www.cnblogs.com/zhangchaoyang/articles/2012070.html