C++中遍历骰子掷出结果的多层嵌套for循环有什么更优替代方案?
你提供的9层循环写法可以覆盖所有6^9=10077696种骰子排列,但可扩展性极差,也不符合现代C++的代码规范,我们可以用逻辑完全等价、性能几乎无差异的通用写法解决该问题。
通用遍历实现(C++17兼容)
我们可以将骰子序列等价为N位6进制数,通过遍历0到总排列数的所有整数,拆分每一位得到对应骰子的取值,实现任意数量骰子的全排列遍历:
#include <array> #include <cstdint> // 模板参数为需要遍历的骰子总个数 template<size_t dice_count> void Evaluate(const ScoringSystem& sys) { // 编译期计算总排列数 constexpr uint64_t total = []() { uint64_t res = 1; for (size_t i = 0; i < dice_count; ++i) res *= 6; return res; }(); for (uint64_t i = 0; i < total; ++i) { std::array<int, dice_count> rolls; uint64_t tmp = i; for (size_t d = 0; d < dice_count; ++d) { rolls[d] = tmp % 6; tmp /= 6; } sys.GetGameResult(rolls.data()); } } // 你的场景直接调用即可:Evaluate<9>(sys)
该实现的优势非常明显:
- 可扩展性极强,调整骰子数量仅需要修改模板参数,不需要改动逻辑代码
- 代码简洁,逻辑清晰,和原始9层循环的遍历结果完全一致
- 性能和原生循环几乎没有差异,1000万次遍历在现代CPU上仅需要几毫秒即可完成
额外优化建议
- 如果需要测试多套不同的计分规则,可以提前预生成所有
rolls序列存储到数组中,后续测试新规则时直接遍历预生成的数组即可,不需要重复计算6进制位拆分逻辑 - 全量遍历的结果准确性远高于随机抽样模拟,1000万级别的计算量完全在普通消费级硬件的能力范围内,不需要牺牲准确性改用模拟方案
内容的提问来源于stack exchange,提问作者Tim Randall
相关产品推荐
相关产品推荐

