Reverse FizzBuzz问题代码重构求助:适配非起始序列输入
Reverse FizzBuzz 问题重构方案
问题核心
原代码默认输出序列从数字1开始,直接用索引+1作为元素对应的真实数值,但实际测试用例的序列是从51开始的,导致Fizz/Buzz的位置计算完全错误,GCD逻辑失效。
解决思路
- 确定真实数值偏移量:从输入序列中提取所有明确的数字,计算每个数字对应的序列位置(索引+1)与真实数值的差值,得到统一偏移量
offset = 真实数值 - (索引+1)。 - 映射真实数值:用每个元素的
索引+1 + offset得到对应的真实数值,再收集Fizz/Buzz对应的真实数值。 - GCD求解乘数:对Fizz对应的真实数值求GCD得到f,对Buzz对应的真实数值求GCD得到b。
重构后的代码
import java.util.ArrayList; import java.util.List; public class FizzBuzzMultiplierFinder { public static void main(String[] args) { // 问题测试用例:预期输出f=5, b=51 String[] input5 = { "Fizz", "Buzz", "52", "53", "54", "Fizz", "56", "57", "58", "59", "Fizz", "61", "62", "63", "64", "Fizz", "66", "67", "68", "69", "Fizz" }; findFizzBuzzMultipliers(input5); // 原测试用例:预期输出f=3, b=5 String[] originalInput = {"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"}; findFizzBuzzMultipliers(originalInput); } public static void findFizzBuzzMultipliers(String[] fizzBuzzOutput) { // 计算偏移量offset Integer offset = null; for (int i = 0; i < fizzBuzzOutput.length; i++) { String elem = fizzBuzzOutput[i]; if (isNumeric(elem)) { int num = Integer.parseInt(elem); int currentOffset = num - (i + 1); if (offset == null) { offset = currentOffset; } else if (offset != currentOffset) { System.err.println("输入序列无效:数字对应的偏移量不一致"); return; } } } if (offset == null) { System.err.println("输入序列中无数字,无法确定偏移量"); return; } // 收集Fizz/Buzz对应的真实数值 List<Integer> fizzNumbers = new ArrayList<>(); List<Integer> buzzNumbers = new ArrayList<>(); for (int i = 0; i < fizzBuzzOutput.length; i++) { String elem = fizzBuzzOutput[i]; int realNum = (i + 1) + offset; if (elem.contains("Fizz")) { fizzNumbers.add(realNum); } if (elem.contains("Buzz")) { buzzNumbers.add(realNum); } } // 计算GCD得到乘数 int f = findGCD(fizzNumbers); int b = findGCD(buzzNumbers); System.out.println("f = " + f + ", b = " + b); } // 判断字符串是否为数字 private static boolean isNumeric(String str) { if (str == null) return false; try { Integer.parseInt(str); return true; } catch (NumberFormatException e) { return false; } } // 计算列表的最大公约数 public static int findGCD(List<Integer> numbers) { if (numbers.isEmpty()) { System.err.println("缺少足够的Fizz/Buzz元素来计算乘数"); return -1; } int gcd = numbers.get(0); for (int num : numbers) { gcd = gcd(gcd, num); } return gcd; } // 两数最大公约数计算 public static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } }
代码说明
- 偏移量兼容:既支持从1开始的常规序列,也支持任意起始数字的序列。
- 输入校验:检查数字偏移量一致性,避免无效输入导致错误结果。
- 逻辑复用:保留原GCD核心逻辑,仅修正数值映射部分,降低重构成本。
内容的提问来源于stack exchange,提问作者Endstone
相关产品推荐
相关产品推荐

