标签:最长公共子序列
最长公共子序列,英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。而最长公共子串(要求连续)和最长公共子序列是不同的。
#include "stdafx.h"
#include<deque>
#include<iostream>
using namespace std;
deque<pair<char, int>>common;
deque<pair<char, int>>max;
deque<deque<pair<char, int>>>aa;
int k = 0;//在str2中找到obj的位置
int kk;
deque<pair<char, int>>char2vec(char*str, int offset)
{
deque<pair<char, int>>aa;
while (*str != '\0')
{
aa.push_back(pair<char, int>(*str, offset));
str++;
offset++;
}
return aa;
}
int find_char(char obj, char*str, int startpos)
{
int len = strlen(str);
while (startpos < len)
{
if (str[startpos] == obj)
return startpos;
startpos++;
}
return -1;
}
void forward(char*str1, char*str2, int n)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
while (n < len1&&k < len2 - 1)
{
kk = find_char(str1[n], str2, k);
if (kk >= 0)
{
common.push_back(pair<char, int>(str1[n], kk));
k = kk;
//if (n<len1 - 1)
aa.push_back(char2vec(str1 + n + 1, n + 1));
}
n++;
}
}
void LMS(char*str1, char*str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
if (len1 > len2)
{
char*temp = str1;
str1 = str2;
str2 = temp;
int tt = len1;
len1 = len2;
len2 = tt;
}
int maxlen = 0;
int n = 0;//str1的索引
forward(str1, str2, n);
if (common.size() > maxlen)
{
maxlen = common.size();
max = common;
}
while (!aa.empty())
{
if (aa.back().empty())
{
aa.pop_back();
common.pop_back();
if (aa.empty())
return;
}
if (common.size() > 1)
{
k = common[common.size() - 2].second + 1;
}
else
{
k = 0;
}
kk = find_char(aa.back().front().first, str2, k);
if (kk >= 0)
{
common.pop_back();
common.push_back(aa.back().front());
common.back().second = kk;//find_char(common.back().first, str2, common[common.size() - 2].second + 1);
k = kk;
n = aa.back().front().second;
aa.back().pop_front();
forward(str1, str2, n + 1);
if (common.size() > maxlen)
{
maxlen = common.size();
max = common;
}
}
else
{
aa.back().pop_front();
if (aa.back().empty())
{
aa.pop_back();
common.pop_back();
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char*str1 = "adecfbaf";
char*str2 = "deabcabaf";
LMS(str1, str2);
for (int i = 0; i < max.size(); i++)
cout << max[i].first << endl;
system("pause");
return 0;
}aa中存放的是未被遍历过的字符,aa里的pair<char,int>里的int代表这个字符在str1中的位置。
整个搜索过程是波浪式前进,common找到一个起点,走到结尾,然后替换common的结尾,再往前走,走到结尾再替换
反复执行,过程中记录common的最大长度即可
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:最长公共子序列
原文地址:http://blog.csdn.net/u014568921/article/details/47729317