笔试遇到的题,看似其貌不扬,我却没AC,一度怀疑是不是自己智商有问题,笔试完下来在LC找到了原题,不得不说LC的边界条件真的很苛刻啊,我以为小数就截取16位呢,原来可以无限长,思路很简单,倒是堵边界堵了俩小时😭
function fractionToDecimal(numerator, denominator) {
// 边界条件————特殊值
if(numerator===0) return '0'
if(denominator===0) return
// 去除负号再运算
let intPart = numerator * denominator > 0 ? '' : '-'
numerator = Math.abs(numerator)
denominator = Math.abs(denominator)
// 获得整数部分
intPart += Math.floor(numerator / denominator)
let floatPart = '', remainder = numerator % denominator
// 整除情况
if (remainder === 0) return intPart
// remainders用来保存每次的余数,余数相同则证明是循环小数,退出while循环
const remainders = []
// floatPart的length是个坑,写大点,不然LC有好多神奇的测试数据让你崩溃😶
while ((remainder !== 0) && (floatPart.length < 10000) && (remainders.indexOf(remainder) === -1)) {
let count = 0
remainders.push(remainder)
while (remainder < denominator) {
if (count !== 0) {
floatPart += Math.floor(remainder / denominator)
}
remainder *= 10
remainders.push(remainder)
count++
}
floatPart += Math.floor(remainder / denominator)
remainder = remainder % denominator
}
if (remainder === 0) {
return intPart + '.' + floatPart
} else {
if (remainders.indexOf(remainder) === -1) {
return intPart + '.' + floatPart
} else {
// remainders存的余数可能会有超过分母大小的情况,应舍去
const index = remainders.filter(item => item < denominator).indexOf(remainder)
const circle = floatPart.slice(index)
const constant = floatPart.slice(0, index)
return `${intPart}.${constant}(${circle})`
}
}
}