C++:试图通过组合和帕斯卡三角形来理解constexpr
C++: Trying to understand constexpr through combinations and Pascal's Triangle
我知道constexpr
应该允许消除/简化过去使用的许多模板编程技巧,但我对C++11还很陌生,在计算组合函数时,我很难理解为什么:
C(n,r) = n!/(r!(n-r)!) = C(n-1,r-1) + C(n-1,r)
递归方法在运行时执行时速度慢得离谱,但允许计算更大值的C(n,r)
,它与模板配合使用很好,但我无法使它与constexpr
配合使用。这是我正在使用的模板代码:
using factorial_t = unsigned long long;
template<size_t N, size_t R>
struct recursive_combinations {
enum: factorial_t { value = recursive_combinations<N-1, R>::value +
recursive_combinations<N-1, R-1>::value};
};
template<size_t N>
struct recursive_combinations<N,0> {
enum: factorial_t { value = 1 };
};
template<size_t N>
struct recursive_combinations<N,N> {
enum: factorial_t { value = 1 };
};
这是constexpr
版本(也许我在这里做错了什么(:
constexpr const factorial_t recursiveCombinations(const size_t N, const size_t R) {
if (R == N || R == 0) return 1;
return recursiveCombinations(N-1, R) + recursiveCombinations(N-1, R-1);
}
当我尝试这个:
constexpr auto comb1_50_30 = recursive_combinations<50,30>::value;
一切都很好,我得到了47129212243960的预期结果,这是通过计算阶乘无法获得的。
然而,当我尝试这个:
constexpr auto comb2_50_30 = recursiveCombinations(50, 30);
编译器(clang v5.0.1,设置为C++17模式(抱怨comb2_50_30
必须由常量表达式初始化。
有人能帮我弄清楚我做错了什么吗?或者是否有办法让constexpr
发挥作用(如果没有,为什么不呢(?
以将结果的限制降低min(r, n-r)
的一个因子为代价,您可以使用以下更有效的实现:
constexpr uint64_t efficientCombinations(uint64_t n, uint64_t r)
{
uint64_t accum = 1U;
if (n - r > r) r = n - r;
for( uint64_t x = 1; x <= n - r; ++x )
{
accum *= (r + x);
accum /= x;
}
return accum;
}
为了与C++11兼容,将此迭代转换为递归非常简单(如果有点混乱的话(。
(注意:根据"让this工作"的意思,这样改变算法可能不是理想的方法……但它太大了,无法发表评论(
抱怨comb2_50_30必须由常量表达式初始化。
错误的下一行告诉原因:
note: constexpr evaluation hit maximum step limit; possible infinite loop?
对于constexpr
评估来说,您的扩展在计算上过于昂贵。您可以使用-fconstexpr-steps=X
和-fconstexpr-depth=X
来增加编译器计算constexpr
函数的工作量,但我没能找到允许recursiveCombinations(50, 30)
在clang上编译的值。
g++编译的CCD_ 14版本很好。
- C++:试图通过组合和帕斯卡三角形来理解constexpr
- 如何在C++的帕斯卡三角形中打印曲棍球棒的元素?
- CUDA - 统一内存(至少是帕斯卡)
- 找到一个数字平方和是质数(帕斯卡或C++)的数字
- 有人知道一个模仿帕斯卡"range array"的类吗?
- 找到第1500行帕斯卡三角形中的每个数字
- 需要使用帕斯卡三角形 (x+y) 打印二项式系数
- 帕斯卡三角形程序 C++ 上的间距
- 为什么我在计算帕斯卡三角形元素时在递归 C 程序中出现堆栈溢出错误
- C++:如何生成帕斯卡三角形的'nth'线?
- 从C++打电话给斯卡拉帕克
- 帕斯卡三角形|李特码错误答案
- 帕斯卡三角形实现
- 帕斯卡的模数
- 以C++为中心帕斯卡三角形输出
- 帕斯卡的读密钥是否有等效项;在 C 还是C++?
- 我如何解释这个帕斯卡部分C++
- 为什么这个帕斯卡三角形程序不起作用?
- c++生成帕斯卡三角形,输出错误
- C++:帕斯卡三角形 - 奇怪的结果