求最長公共子序列
阿新 • • 發佈:2017-06-11
ade empty 全部 str2 comm star 要求 longest strlen
上述算法中common中存放當前找到的子序列。common裏的pair<char,int>裏的int代表這個字符在str2中的位置。
最長公共子序列,英文縮寫為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的最大長度就可以
求最長公共子序列