我有以下代码计算给定n和k的第二种斯特林数,
#include <cstdint>
#include <map>
#include <boost/multiprecision/cpp_int.hpp>
namespace mp = boost::multiprecision;
mp::cpp_int stirlingS2(unsigned n, unsigned k)
{
if (n == 0 && k == 0) {
return 1;
}
if (n == 0 || k == 0) {
return 0;
}
static auto memo = std::map<std::pair<unsigned, unsigned>, mp::cpp_int>();
auto nKPair = std::pair<unsigned, unsigned>(n, k);
if (memo.count(nKPair) > 0) {
return memo[nKPair];
}
auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1);
memo[nKPair] = val;
return val;
}
不幸的是,当这段代码运行时,会出现段错误。对于插入memo
的前87795值似乎运行正常,但此后不久就崩溃了。具体而言,段错误发生在map::count
行if (memo.count(nKPair) > 0) {
中。我想也许这是memo
超出规模的问题,所以我在memo
的作业中添加了以下警告,
if (memo.size() < memo.max_size()) {
memo[nKPair] = val;
}
但这并没有帮助。我还注意到87795值并不表示何时崩溃。通过一些小修改,将第一个if语句更改为,
if (n <= k) {
return 1;
}
将该值更改为66453。
有谁知道这里发生了什么?
答案 0 :(得分:1)
好的,经过几个小时的混乱之后,我将其缩小为表达式模板问题。我并不完全理解为什么,但这一切都与行
中的那个小auto
有关
auto val = k * stirlingS2(n - 1, k) + stirlingS2(n - 1, k - 1)
基本上,将auto
更改为mp::cpp_int
,然后突然,不会出现段错误。