[leetcode] 166. Fraction to Recurring Decimal

给定两个整数,表示分数的分子和分母,返回该分数的小数形式字符串。如果小数部分是循环的,则将循环部分用括号括起来。例如,给定分子2和分母3,返回'0.(6)'。问题的关键在于使用哈希表来检测余数是否重复,以判断小数是否无限循环,并处理负数和循环部分的括号插入。
摘要由CSDN通过智能技术生成

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

For example,

  • Given numerator = 1, denominator = 2, return "0.5".
  • Given numerator = 2, denominator = 1, return "2".
  • Given numerator = 2, denominator = 3, return "0.(6)".

这道题是分数转换为小数,题目难度为Medium。

要将分数转换为小数,可以从小数的计算过程着手。以1/8为例,分为以下几步:

  • 商为0,余数为1,记录当前的商,开始进入小数部分,至此小数为“0.”

  • 拿余数1乘10作为新的分子继续计算,商为1,余数为2,至此小数为“0.1”

  • 拿余数2乘10作为新的分子继续计算,商为2,余数为4,至此小数为“0.12”

  • 拿余数4乘10作为新的分子继续计算,商为5,余数为0,计算结束,最终小数为“0.125”

题目的关键部分在于判断分数是否是无限循环小数,如果计算过程中当前余数和之前的余数相同,说明小数开始循环,就可以结束计算了。要判断余数是否重复出现过,自然会想到用Hash Table。另外题目还需要注意两点:分子和分母有可能是负数,如果符号不同结果中要有负号;分数是无限循环小数时要在结果中加入括号,因此需要在Hash Table中记录下余数出现的位置,重复出现时在该位置之前插入左括号。运算结束的条件是余数为0或者余数出现重复。具体代码:

class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        string rst;
        unordered_map<long long, int> hash;
        int pos;
        long long quotient, remainder, curNum, curDen;

        if((numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0)) rst += "-";
        if(numerator < 0) curNum = abs((long long)numerator);
        else curNum = numerator;
        if(denominator < 0) curDen = abs((long long)denominator);
        else curDen = denominator;
        quotient = curNum / curDen;
        remainder = curNum % curDen;
        
        rst += to_string(quotient);
        if(remainder) rst += ".";
        
        pos = rst.size();
        hash[remainder] = pos;
        
        while(remainder) {
            curNum = remainder * 10;
            remainder = curNum % curDen;
            quotient = curNum / curDen;
            
			rst += to_string(quotient);
            if(remainder == 0) {
                break;
            }
            else {
                auto it = hash.find(remainder);
                if(it != hash.end()) {
                    rst.insert(it->second, "(");
                    rst += ")";
                    break;
                }
                else {
					pos++;
                    hash[remainder] = pos;
                }
            }
        }
        
        return rst;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值