编程练习-动态规划(最长公共子序列LCS)
2012-02-03 20:19
483 查看
程序代码如下:
关键是下标的处理问题,容易出现错误的几点是:
1)保存矩阵的行列数量要计算清楚,矩阵多出1行和1列用于存储初始值,这样初始时i-1和j-1的位置不会溢出
2)由于矩阵的下标从1开始,而传入的向量下标从0开始,因此访问向量时下标要-1,对于Print函数也是如此
3)注意DualArray的常量成员函数实现,为了满足常量参数调用的需要,内部需要转型操作
4)Print的实现允许用户定义的访问函数,通过函数模板参数实现
#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)C语言加注释
- 最长公共子序列(LCS)(一)---动态规划
- Java-LCS最长公共子序列(动态规划实现)
- 动态规划_求最长公共子序列LCS
- Nod-最长公共子序列Lcs(动态规划)
- SDAU 编程练习三 动态规划和动态规划与背包问题相结合的问题
- [动态规划] LCS最长公共子序列问题
- 51nod 1006 最长公共子序列Lcs(经典动态规划)
- 编程之美3.3——类似——两个字符串的最长公共子序列(LCS)
- 算法导论——动态规划之最长公共子序列(LCS)和最长回文子序列(LPS)
- LCS最长公共子序列――动态规划
- 0011算法笔记——【动态规划】最长公共子序列问题(LCS)
- 动态规划 最长公共子序列(LCS)问题
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- 自顶向下动态规划解决最长公共子序列(LCS)问题
- Dynamic Programming longest common subsequence(LCS) 动态规划之最长公共子序列
- 最长公共子序列(LCS---动态规划)
- 动态规划----最长公共子序列LCS