日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最长公共字序列

發布時間:2025/7/25 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最长公共字序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最長公共子序列,英文縮寫為LCSLongest?Common?Subsequence)。

定義:一個序列?S?,如果分別是兩個或多個已知序列的子序列,且是所有符合此條件序列中最長的,則?S?稱為已知序列的最長公共子序列。

兩個字符串的最長子序列并不要求字符串連續,只要求有序,即統計兩個字符串有多少個重復的字符。用動態規劃的思路做。

C[i][j]記錄以X[i]為結尾的字符串與Y[j]為結尾的字符串的LCS?的長度,分兩組情況考慮:

1)X[i]?==?Y[j],則

C[i][j]的結果可以根據C的定義通過C[i-1][j-1],得到

2)X[i]?/=?Y[j],則

轉化為C[i][j-1]C[i-1][j]的結果,

具體公式如下

?

如下是具體的實現

int LongestCommonLength(const std::string& first, const std::string& last) {const size_t first_size = first.size();const size_t last_size = last.size();if (!first_size || !last_size ) {return 0;}// 用空間換時間size_t cost_map[first_size + 1][last_size + 1];memset(cost_map, 0, sizeof(cost_map));size_t max_len = 0;for (int i = 1; i <= first_size; ++i ){for (int j = 1; j <= last_size ; ++j ) {if ((first[j-1] == last[i-1])) {cost_map[i][j]=cost_map[i-1][j-1]+1;putchar(first[j-1]);} else {cost_map[i][j] = std::max(cost_map[i][j-1],cost_map[i-1][j]);}if (max_len < cost_map[i][j]) {max_len = cost_map[i][j];}printf("%ld\t", cost_map[i][j]);} // end-forprintf("\n");}
return? max_len;
}

程序代碼中,未來減少對j-1=0的判斷,對每一行多分配一個存儲單元。

遍歷cost_map可以求出具體的子序列,

代碼示例為

int k = max_len;int i = first_size;int j = last_size;while (k > 0) {if (cost_map[i][j] == cost_map[i-1][j]) {--i;} else if (cost_map[i][j] == cost_map[i][j-1]) {--j;} else {putchar(first[i-1]);--j, --i;--k;}}putchar('\n');

putchar的順序為逆序,reverse一下即可。

如果不需要求公共子序列,C[i][j]其實只需要兩維即可,可以看到,每次只需要兩列即可,此方法在某一列很大的時候,比較好,具體實現為

  int LongestCommonLength(const std::string& first, const std::string& last) {const size_t first_size = first.size();const size_t last_size = last.size();if (!first_size || !last_size ) {return 0;}size_t map_size = first_size + 1;size_t cost_map[map_size<<1];memset(cost_map, 0, sizeof(cost_map));size_t* prev_map = cost_map;size_t* next_map = &cost_map[map_size];size_t max_len = 0;int end_pos = 0;for (int i = 1; i <= last_size; ++i ){for (int j = 1; j <= first_size ; ++j ) {if ((first[j-1] == last[i-1])) {next_map[j] = prev_map[j-1] + 1;} else {next_map[j] = std::max(next_map[j-1], prev_map[j]);}if (max_len < next_map[j]) {max_len = next_map[j];end_pos = j;}printf("%ld\t", next_map[j]);} // end-for    std::swap(prev_map, next_map); // prev clearprintf("\n");} // end-forreturn max_len; }

?

?

?

轉載于:https://www.cnblogs.com/westfly/archive/2013/03/18/2967049.html

總結

以上是生活随笔為你收集整理的最长公共字序列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。