力扣面试题解析 116.将分数转换为小数,将结果一字符串的形式进行输出,重复的部分用()进行包裹
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
示例 1:
输入: numerator = 1, denominator = 2
输出: "0.5"
示例 2
输入: numerator = 2, denominator = 1
输出: "2"
示例 3
输入: numerator = 2, denominator = 3
输出: "0.(6)"
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/fr… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
整体的代码如图
var fractionToDecimal = function(numerator, denominator) {
if(!numerator)
return "0";
// 存储商
var result = [];
// 保存余数
var remain = 0;
// 记录当前余数的位置
var map = new Map();
// 判断结果的正负
if(numerator < 0 ^ denominator < 0)
result.push("-");
// 取两个数的绝对值
var num = Math.abs(numerator);
var deno = Math.abs(denominator);
// 取整数部分
result.push(Math.floor(num / deno).toString());
// 余数
remain = num % deno;
// 有余数
if(remain)
result.push(".");
while(remain){
// 当出现重复的余数时,代表商开始进行循环
if(map.has(remain)){
// 当第二个参数是0,会在指定位置的前面插入第三个参数
result.splice(map.get(remain), 0, "(");
result.push(")");
break;
}
/*
记录当前余数
当前余数对应的是商的位置
商的位置,在上面的商的循环处理需要使用
*/
map.set(remain, result.length);
remain *= 10;
// 加入新的商
result.push(Math.floor(remain / deno).toString());
remain %= deno;
}
return result.join("");
};
if(numerator < 0 ^ denominator < 0)
result.push("-");
- 这是为了判断输入的两个数的正负关系
- 先对两个数进行正负的判断
- 使用^(异或运算)即可得到商的正负值
// 取整数部分
result.push(Math.floor(num / deno).toString());
- 这一部分是用于在进入
while循环之前的商的获取,在此处不可以使用parseInt进行整数部分的获取
while内的循环的代码
// 当出现重复的余数时,代表商开始进行循环
if(map.has(remain)){
// 当第二个参数是0,会在指定位置的前面插入第三个参数
result.splice(map.get(remain), 0, "(");
result.push(")");
break;
}
/*
记录当前余数
当前余数对应的是商的位置
商的位置,在上面的商的循环处理需要使用
*/
map.set(remain, result.length);
remain *= 10;
// 加入新的商
result.push(Math.floor(remain / deno).toString());
remain %= deno;
- 使用
map记录当前余数和下一个商的位置 - 在下面会向商的数组
result中加入新的商 - 重新计算现在的余数
- 在第二次循环的
if判断才是有意义的,这时需要判断现在的余数在map集合中是否有重复的,有重复的代表商开始进行循环了 - 当商开始循环后,这时候就可以对之前存储的商进行处理,使用
splice为出现循环的第一个数字的前面加上(,最后在结尾处加上),将结果输出即可