编程练习-动态规划(最长公共子序列LCS)
来源:互联网 发布:燃烧冰flamingo数据 编辑:程序博客网 时间:2024/06/07 00:43
程序代码如下:
#include <stdio.h>#include <vector>#include <boost/scoped_ptr.hpp>template<typename T>class DualArrayInternal { public: DualArrayInternal(T* array_data, size_t column_num) : array_data_(array_data), column_num_(column_num) { } T& operator[](size_t y) { return array_data_[x_ * column_num_ + y]; } const T& operator[](size_t y) const { return array_data_[x_ * column_num_ + y]; } void SetX(size_t x) { x_ = x; } private: size_t x_; T* array_data_; size_t column_num_;};template<typename T>class DualArray { public: DualArray(T* array_data, size_t column_num) : internal_(array_data, column_num) {} DualArrayInternal<T>& operator[](size_t x) { internal_.SetX(x); return internal_; } const DualArrayInternal<T>& operator[](size_t x) const{ const_cast<DualArray*>(this)->internal_.SetX(x); return internal_; } private: DualArrayInternal<T> internal_;};void Print(int value) { printf("%c", value);}template<typename T, typename PrintFun>void PrintSequence(const std::vector<T>& array1, const DualArray<char>& path_direction, const size_t i, const size_t j, PrintFun print_fun) { if (i == 0 || j == 0) { return; } if (path_direction[i][j] == 'S') { PrintSequence(array1, path_direction, i - 1, j - 1, print_fun); print_fun(array1[i - 1]); } else if(path_direction[i][j] == 'U') { PrintSequence(array1, path_direction, i - 1, j, print_fun); } else { PrintSequence(array1, path_direction, i, j - 1, print_fun); }}template<typename T>void LongestCommonSubsequence(std::vector<T>& array1, const std::vector<T>&array2) { boost::scoped_ptr<size_t> subsequence_length_buffer(new size_t[(array1.size() + 1) * (array2.size() + 1)]); DualArray<size_t> subsequence_length(subsequence_length_buffer.get(), array2.size() + 1); boost::scoped_ptr<T> path_direction_buffer(new char[(array1.size() + 1) * (array2.size() + 1)]); DualArray<char> path_direction(path_direction_buffer.get(), array2.size() + 1 ); for (size_t i = 0; i <= array1.size(); ++i) { subsequence_length[i][0] = 0; } for (size_t j = 0; j <= array2.size(); ++j) { subsequence_length[0][j] = 0; } for (size_t i = 1; i <= array1.size(); ++i) { for (size_t j = 1; j <= array2.size(); ++j) { if (array1[i - 1] == array2[j - 1]) { subsequence_length[i][j] = subsequence_length[i - 1][j - 1] + 1; path_direction[i][j] = 'S'; } else if (subsequence_length[i - 1][j] >= subsequence_length[i][j - 1]) { subsequence_length[i][j] = subsequence_length[i - 1][j]; path_direction[i][j] = 'U'; } else { subsequence_length[i][j] = subsequence_length[i][j - 1]; path_direction[i][j] = 'L'; } } } for (int i = 0; i <= array1.size(); ++i) { for(int j = 0; j <= array2.size(); ++j) { printf("%zd ", subsequence_length[i][j]); } printf("\n"); } PrintSequence(array1, path_direction, array1.size(), array2.size(),Print); printf("\n");}class Test{};int main(int argc, char** argv) { char array1[] = {'B', 'D', 'C', 'A', 'B', 'A'}; std::vector<char> array_vector1(array1, array1 + sizeof(array1) / sizeof(char)); char array2[] = {'A', 'B', 'C', 'B', 'D', 'A', 'B'}; std::vector<char> array_vector2(array2, array2 + sizeof(array2) / sizeof(char)); LongestCommonSubsequence<char>(array_vector2, array_vector1);}
关键是下标的处理问题,容易出现错误的几点是:
1)保存矩阵的行列数量要计算清楚,矩阵多出1行和1列用于存储初始值,这样初始时i-1和j-1的位置不会溢出
2)由于矩阵的下标从1开始,而传入的向量下标从0开始,因此访问向量时下标要-1,对于Print函数也是如此
3)注意DualArray的常量成员函数实现,为了满足常量参数调用的需要,内部需要转型操作
4)Print的实现允许用户定义的访问函数,通过函数模板参数实现
- 编程练习-动态规划(最长公共子序列LCS)
- 【动态规划】最长公共子序列LCS
- 动态规划---LCS最长公共子序列
- 动态规划-最长公共子序列【LCS】
- 动态规划-最长公共子序列(LCS)
- 动态规划-LCS最长公共子序列
- 动态规划----最长公共子序列LCS
- (动态规划)LCS-最长公共子序列
- 动态规划 最长公共子序列LCS
- 动态规划 最长公共子序列LCS、最长公共连续子串、最长重复子串
- 动态规划实现最长公共子序列(LCS)算法
- 动态规划之最长公共子序列(lcs)
- 动态规划之最长公共子序列(lcs)
- 动态规划---LCS问题 最长公共子序列
- 动态规划;最长公共子序列;LCS问题;
- 动态规划—最长公共子序列LCS
- 动态规划经典问题---最长公共子序列(LCS)
- 动态规划算法解最长公共子序列LCS问题
- 不走寻常路的常识逻辑学家:Lisp之父约翰•麦卡锡
- 微软发布官方TFS 2010 Scrum 模板
- 热点块竞争和解决--cache buffers chains
- Install OpenVPN Server on CentOS 5.4
- Using Google Maps in Android
- 编程练习-动态规划(最长公共子序列LCS)
- WCF 学习记录(2)
- RMAN不完全恢复
- 浅谈.NET平台
- 死锁和活锁
- Oracle 10g RAC裸设备管理方式切换
- Android 2.2 下 camera 应用程序支持 GPS 信息写入 jpeg 文件
- 心烦
- 控件学习(三)