C++ FizzBuzz程序未输出Fizz的问题排查求助
FizzBuzz程序无法输出"fizz"问题排查
问题概述
在Compiler Explorer中实现了规则与逻辑分离的FizzBuzz程序,未使用IDE或调试工具。程序可正常输出数字和"buzz",但始终无法输出"fizz"。
原代码
#include <cstdint> #include <map> #include <string> #include <iostream> // 原代码遗漏该头文件,std::cout依赖它才能运行 typedef std::map<uint32_t,std::string> RuleSet; RuleSet ruleSet { {3, "fizz"}, {5, "buzz"} }; void fizzBuzz(int32_t max_limit, RuleSet rules) { std::string output{""}; for (uint32_t i = 1; i < max_limit; i++) { for (auto r : rules) { if ( (i % r.first) == 0 ) { output = r.second; } else { output = std::to_string(i); } } output.append(1, '\n'); std::cout << output; output.clear(); } } int main() { fizzBuzz(100, ruleSet); return 0; }
预期输出
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz // 以此类推...
实际输出
1 2 3 4 buzz 6 7 8 9 buzz 11 12 13 14 buzz 16 17 18 19 buzz 21 22 23 24 buzz 26 27 28 29 buzz 31 32 33 34 buzz 36 37 38 39 buzz 41 42 43 44 buzz 46 47 48 49 buzz 51 52 53 54 buzz 56 57 58 59 buzz 61 62 63 64 buzz 66 67 68 69 buzz 71 72 73 74 buzz 76 77 78 79 buzz 81 82 83 84 buzz 86 87 88 89 buzz 91 92 93 94 buzz 96 97 98 99
问题根源
核心问题是遍历规则时的覆盖赋值逻辑:
std::map是有序容器,会先遍历键为3的规则,再遍历键为5的规则。- 以i=3为例:
- 第一次循环(匹配3的规则):满足条件,
output被设为"fizz"。 - 第二次循环(匹配5的规则):3%5≠0,
output被覆盖为"3",最终输出数字而非"fizz"。
- 第一次循环(匹配3的规则):满足条件,
- 以i=5为例:
- 第一次循环(匹配3的规则):5%3≠0,
output被设为"5"。 - 第二次循环(匹配5的规则):满足条件,
output被覆盖为"buzz",因此能正常输出"buzz"。
- 第一次循环(匹配3的规则):5%3≠0,
- 这种每次循环直接覆盖
output的逻辑,会让前面规则的结果被后面的规则覆盖,除非后面的规则也满足条件。
修复方案
修改逻辑为追加字符串而非覆盖,仅当无规则匹配时才赋值为数字:
#include <cstdint> #include <map> #include <string> #include <iostream> typedef std::map<uint32_t,std::string> RuleSet; RuleSet ruleSet { {3, "fizz"}, {5, "buzz"} }; void fizzBuzz(int32_t max_limit, const RuleSet& rules) { // 传const引用避免不必要拷贝 std::string output; for (uint32_t i = 1; i < max_limit; ++i) { output.clear(); for (const auto& r : rules) { // 用const引用遍历,避免拷贝 if (i % r.first == 0) { output += r.second; // 追加字符串而非覆盖 } } // 无规则匹配时,赋值为数字字符串 if (output.empty()) { output = std::to_string(i); } output += '\n'; std::cout << output; } } int main() { fizzBuzz(100, ruleSet); return 0; }
修复后效果
程序将正常输出"fizz"、"buzz"以及"fizzbuzz",与预期输出一致。
内容的提问来源于stack exchange,提问作者Francis Cugler
相关产品推荐
相关产品推荐

