LeetCode166 分数到小数

目录 

题目

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 10^4 。

分析 长除法

分数化小数,可能的结果有三种:整数、有限小数、无限循环小数。

先判断分子/分母能不能整除,可以就直接返回
否则,先判断一下结果的正负号
再对分子分母取绝对值,整除一下就得到了整数部分
关键是小数部分
取分子/分母的余数,乘10,再除分母,可得到一位小数。除分母留下的余数,再乘10...就这样一直循环算小数。
那么,什么时候停止呢?
余数*10/分母能够整除,说明它是有限小数
②我们在上面循环的时候,将每一轮循环的余数*10这个数,存到一个map对象中
当我们发现map对象中开始有重复值了,就停止循环,说明它有循环节,是无限循环小数
保存这个第一个开始重复的值,也就是循环节的第一个字符,用来规范结果的格式。 

/**
 * @param {number} numerator
 * @param {number} denominator
 * @return {string}
 */
var fractionToDecimal = function(numerator, denominator) {
    // 如果结果为整数
    if(numerator % denominator == 0) {
        return '' + numerator / denominator;
    }
    const sb = [];
    // 判断结果的符号
    if(numerator < 0 ^ denominator < 0) {
        sb.push('-');
    }
    // 整数部分
    numerator = Math.abs(numerator)
    denominator = Math.abs(denominator);
    const integerPart = Math.floor(numerator / denominator);
    sb.push(integerPart);
    sb.push('.');
    // 小数部分
    const fractionPart = [];
    const remainderIndecDic = new Map();
    let remainder = numerator % denominator;
    let index = 0;
    while(remainder !== 0 && !remainderIndecDic.has(remainder)) {
        remainderIndecDic.set(remainder, index);
        remainder *= 10;
        fractionPart.push(Math.floor(remainder / denominator));
        remainder %= denominator;
        index++;
    }
    // 小数部分有循环节
    if(remainder !== 0) {
        let insertIndex = remainderIndecDic.get(remainder);
        fractionPart.splice(insertIndex, 0,'(');
        fractionPart.push(')');
    }
    sb.push(fractionPart.join(''));
    return sb.join('');
};

你可能感兴趣的