使用在一对int,int和int上模板化的映射实现memoization表

时间:2011-12-07 09:32:14

标签: c++ map memoization

我已经实现了递归算法,以提高我想要添加memoization表的性能。我问题最自然的结构是

map<pair<int,int>,int> lookup_table;

我使用的递归算法是

int max_sum_path(int maximum_rows,vector<vector<int> >& matrix,int row_index,int colm_index)
{
  if(row_index >= maximum_rows || colm_index > row_index)
  {
    //we have reached a cell outside the Triangular Matrix
    return 0;
  }
  else if(lookup_table.find(row_index,colm_index) != lookup_table.end())
  {
    //the memoization step to avoid repeated calculations and make recursion more efficient
    return lookup_table[row_index,colm_index];
  }
  else
  {
    lookup_table[row_index,colm_index] = matrix[row_index][colm_index] + max(max_sum_path(maximum_rows,matrix,row_index+1,colm_index), max_sum_path(maximum_rows,matrix,row_index+1,colm_index+1));
    return lookup_table[row_index,colm_index];
  }
}

这会引发大量的编译器错误。我不确定语法是否正确。 我应该使用字符串缓冲区来创建字符串,然后使用它而不是对吗?

以下是编译器错误:

sums_triangle.cpp: In function ‘int max_sum_path(int, std::vector<std::vector<int> >&, int, int)’:
sums_triangle.cpp:50:49: error: no matching function for call to ‘std::map<std::pair<int, int>, int>::find(int&, int&)’
sums_triangle.cpp:50:49: note: candidates are:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:736:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) [with _Key = std::pair<int, int>, _Tp = int, _Compare = std::less<std::pair<int, int> >, _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:736:7: note:   candidate expects 1 argument, 2 provided
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:751:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) const [with _Key = std::pair<int, int>, _Tp = int, _Compare = std::less<std::pair<int, int> >, _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:751:7: note:   candidate expects 1 argument, 2 provided
sums_triangle.cpp:53:35: warning: left operand of comma operator has no effect [-Wunused-value]
sums_triangle.cpp:53:45: error: no match for ‘operator[]’ in ‘lookup_table[(0, colm_index)]’
sums_triangle.cpp:53:45: note: candidate is:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::pair<int, int>, _Tp = int, _Compare = std::less<std::pair<int, int> >, _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note:   no known conversion for argument 1 from ‘int’ to ‘const key_type& {aka const std::pair<int, int>&}’
sums_triangle.cpp:57:28: warning: left operand of comma operator has no effect [-Wunused-value]
sums_triangle.cpp:57:38: error: no match for ‘operator[]’ in ‘lookup_table[(0, colm_index)]’
sums_triangle.cpp:57:38: note: candidate is:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::pair<int, int>, _Tp = int, _Compare = std::less<std::pair<int, int> >, _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note:   no known conversion for argument 1 from ‘int’ to ‘const key_type& {aka const std::pair<int, int>&}’
sums_triangle.cpp:58:35: warning: left operand of comma operator has no effect [-Wunused-value]
sums_triangle.cpp:58:45: error: no match for ‘operator[]’ in ‘lookup_table[(0, colm_index)]’
sums_triangle.cpp:58:45: note: candidate is:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note: std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::pair<int, int>, _Tp = int, _Compare = std::less<std::pair<int, int> >, _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/../../../../include/c++/4.6.2/bits/stl_map.h:445:7: note:   no known conversion for argument 1 from ‘int’ to ‘const key_type& {aka const std::pair<int, int>&}’
sums_triangle.cpp:60:1: warning: control reaches end of non-void function [-Wreturn-type]

为了清楚起见,我不确定语法是否正确。我想知道如何使用一对作为地图的关键。

额外信息: 我之前曾问过this个问题。我现在正在优化它。随意为memoization表建议一个不同的结构。

4 个答案:

答案 0 :(得分:2)

而不是这个,

lookup_table.find(row_index,colm_index) //incorrect - your code

写这个,

lookup_table.find(std::make_pair(row_index,colm_index)) //correct - my code

同样也可以看到这些,

lookup_table[row_index,colm_index];  //incorrect  - your code
lookup_table[std::make_pair(row_index,colm_index)]; //correct - my code

说明:

由于lookup_tablestd::map<std::pair<int,int>,int>,其密钥类型为std::pair<int,int>,因此当您使用lookup_table运算符时,[]的索引必须是其关键字

std::make_pair是一个实用程序函数,如果std::pair<int,int>的两个参数都是std::make_pair,则返回int类型的对象。您可以使用std::make_pair而不是写std::pair<int,int>(row_index,colm_index),但这看起来很麻烦,这就是首选std::make_pair的原因。

答案 1 :(得分:1)

不幸的是,这不是python。 您不能使用以下语法:

lookup_table[row_index,colm_index]

您需要使用make_pair()来创建对:

lookup_table[std::make_pair(row_index,colm_index)]

除此之外,您可能应该使用从map.find()返回的迭代器来返回您的memoized结果。就像现在一样,你正在进行两次查找。

答案 2 :(得分:1)

row_indexcolm_index存储在std::pair

pair<int, int> map_key_value = std::make_pair(row_index, colm_index);

然后在map_key_valuelookup_table.find()中使用lookup_table[]

答案 3 :(得分:1)

您无法使用map<pair<int,int>,int>lookup_table[row_index,colm_index]访问find(row_index,colm_index)。要访问它,您必须创建一对两个整数。