求最长公共子序列

来源:互联网 发布:c语言md5加密 编辑:程序博客网 时间:2024/05/16 06:56

最长公共子序列,英文缩写为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;}

上述算法中common中存放当前找到的子序列,common里的pair<char,int>里的int代表这个字符在str2中的位置,

aa中存放的是未被遍历过的字符,aa里的pair<char,int>里的int代表这个字符在str1中的位置。

整个搜索过程是波浪式前进,common找到一个起点,走到结尾,然后替换common的结尾,再往前走,走到结尾再替换

反复执行,过程中记录common的最大长度即可




0 0
原创粉丝点击