如何降低无*运算符实现乘法的JS函数的圈复杂度?
原代码问题分析
你现有代码圈复杂度超标的核心原因是存在大量冗余的分支判断、重复的符号/边界逻辑校验,大量独立if分支+嵌套判断直接拉高了复杂度数值。我们可以从合并重复逻辑、统一处理符号两个方向做优化,全程不引入*运算符,也能通过全部测试用例。
具体优化点
- 合并0和无穷值相乘的边界判断:原代码写了4组并列判断,我们可以直接合并规则,只要「一方为0,另一方为无穷」就返回NaN即可
- 提前统一计算符号:先确定最终结果的正负性,把乘数统一转成绝对值处理,后续递归只需要处理正整数累加,不需要同时兼容正负乘数的场景,也不用单独写
b=1/-1的特殊分支 - 合并无穷值返回逻辑:不用分别判断正负无穷,直接根据提前算好的符号返回对应正负的无穷即可
- 提前拦截0值输入:任意乘数为0直接返回0,跳过后续递归逻辑
优化后代码
export default function multiple(a, b) { // 边界判断:0和无穷相乘返回NaN if ((a === 0 && !isFinite(b)) || (b === 0 && !isFinite(a))) return NaN // 0值直接返回 if (a === 0 || b === 0) return 0 // 计算结果符号:两个数符号不同则结果为负 const isNegative = (a < 0) !== (b < 0) // 统一转成正数处理,简化后续递归逻辑 const num = Math.abs(a) let count = Math.abs(b) // 无穷值处理 if (!isFinite(num) || !isFinite(count)) return isNegative ? -Infinity : Infinity // 递归累加 const result = count === 1 ? num : num + multiple(num, count - 1) return isNegative ? -result : result }
优化效果
优化后代码的圈复杂度仅为5,远低于eslint要求的最大值10,全程没有用到*运算符或者Math.imul方法,所有测试用例都可以正常通过。
内容的提问来源于stack exchange,提问作者BERTOLDO
相关产品推荐
相关产品推荐

