二维数组指定列元素LCM计算错误排查及任意长度LCM求解
问题分析与解决方案
代码错误原因
你的代码中循环条件误用了lst.GetLength(1)——二维数组的GetLength(0)代表行数,GetLength(1)代表列数。输入的{{1,2},{1,3},{1,4}}是3行2列的数组,GetLength(1)的值为2,导致循环仅执行1次(i从1到1),只计算了前两个分母(2和3)的LCM(6),漏掉了第三个分母4,最终结果错误。
修正后的代码
static long LCM(long a, long b) { if (a == 0 || b == 0) return 0; // 根据业务需求处理0的情况,此处默认返回0 return (a / GCD(a, b)) * b; // 先除后乘,避免a*b直接溢出long范围 } static long GCD(long a, long b) => b == 0 ? a : GCD(b, a % b); public static void convertFrac(long[,] lst) { StringBuilder sb = new StringBuilder(); long lcm = lst[0, 1]; // 遍历所有行,GetLength(0)获取总行数 for(int i = 1; i < lst.GetLength(0); i++) { lcm = LCM(lcm, lst[i, 1]); } Console.WriteLine(lcm); }
核心修正点:
- 循环条件改为
i < lst.GetLength(0),确保遍历每一行的第1列元素 - 优化
LCM计算顺序,先除以GCD再乘另一个数,规避大数相乘导致的溢出问题
任意长度数值集合的LCM计算方法
LCM具有结合性,即LCM(a,b,c) = LCM(LCM(a,b), c),因此任意长度集合的LCM可通过迭代实现:
- 初始化当前LCM为集合的第一个元素
- 依次遍历剩余元素,将当前LCM与元素计算新的LCM并更新
- 遍历完成后,当前LCM即为整个集合的LCM
通用集合LCM实现示例
static long CalculateLCM(IEnumerable<long> numbers) { if (numbers == null || !numbers.Any()) throw new ArgumentException("集合不能为空"); long currentLcm = numbers.First(); foreach (long num in numbers.Skip(1)) { currentLcm = LCM(currentLcm, num); if (currentLcm == 0) // 若集合包含0,LCM直接为0,可提前终止循环 break; } return currentLcm; }
使用时,只需提取二维数组中[n,1]的元素组成集合传入:
long[,] lst = {{1,2},{1,3},{1,4}}; var denominators = Enumerable.Range(0, lst.GetLength(0)).Select(i => lst[i, 1]); long lcm = CalculateLCM(denominators); Console.WriteLine(lcm); // 输出12
内容的提问来源于stack exchange,提问作者conrad szyman
相关产品推荐
相关产品推荐

