我正在 C++ 中实现二项式系数(n 选择 k)函数。
除了使用“正常”函数(在运行时评估)之外,还可以使用模板元编程来完成(当参数在编译时已知时):
template <unsigned int n, unsigned int k>
struct Binomialkoeffizient {
static const unsigned int value = Binomialkoeffizient<n, k-1>::value * (n-k+1) / k;
};
template <unsigned int n>
struct Binomialkoeffizient<n, 0> {
static const unsigned int value = 1;
};
这种实现的缺点是,它没有利用定理 n 选择 k = n 在 k > n/2 的情况下选择 n-k。因此可能会发生不必要的算术溢出,例如49 选择 43 会溢出,而 49 选择 6 不会溢出。
我尝试了以下方法来改善这一点:
template <unsigned int n, unsigned int k>
struct Binomialkoeffizient {
static const unsigned int value = (2*k > n) ? Binomialkoeffizient<n, n-k>::value : Binomialkoeffizient<n, k-1>::value * (n-k+1) / k;
};
template <unsigned int n>
struct Binomialkoeffizient<n, 0> {
static const unsigned int value = 1;
};
不幸的是,我得到fatal error: template instantiation depth exceeds maximum of 900
.
这似乎是由于在递归模板实例化过程中没有计算三元运算符造成的。
有哪些可能的替代方法?:
?
我对 C++11 之前的解决方案和较新的解决方案感兴趣(也许std::enable_if
有帮助,但我对此不太了解)。