力扣面试题 116题的详细解析,将分数转换为小数

351 阅读29分钟

力扣面试题解析 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为出现循环的第一个数字的前面加上(,最后在结尾处加上),将结果输出即可