Leetcode 166. Fraction to Recurring Decimal

好久没做模拟题了,所以找个感觉,教训,写之前一定要理好逻辑。

题目:
166. Fraction to Recurring Decimal
Medium

401

904

Favorite

Share
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.

Example 1:

Input: numerator = 1, denominator = 2
Output: “0.5”
Example 2:

Input: numerator = 2, denominator = 1
Output: “2”
Example 3:

Input: numerator = 2, denominator = 3
Output: “0.(6)”

题意:就是给两个数,然后求他们的商。如果有循环节,用括号括起来。

其实想法很简单,有两种情况:

1)如果出现了相同的余数,肯定是有循环节的。
2) 除尽,余数为0

然后很多种情况得讨论,最重要的就是正负号。

还有循环节怎么找,我们使用hash即可,

记住 循环节一定是上1次出现和这次出现之间的那个商,是左开右闭的。

我们模拟一次即可, 1/6

最开始 mp[1] = 2
 10 /6 = 1 ...4 则 mp[4] = 3
 40/6 = 4 ...4  则 mp[4]出现了 
 所以循环节是[3,3]

当然还要考虑,最开始不是有个数量级的,比如1,333 这种的提前凑出同一个数量级。

代码:

class Solution
{
public:
    string fractionToDecimal(int numerator, int denominator)
    {
        long long num1 = numerator;
        long long num2 = denominator;
        if(num1 == 0 ) return to_string(0);
        if(num2==1) return to_string(numerator);
        if(num1%num2==0) return to_string(num1/num2);
        else if(denominator==-1)
        {
            long long temp = numerator;
            return to_string(-temp);
        }
        bool op = true;
        if(num1<0 && num2<0)
        {
            num1 = -num1;
            num2 = -num2;
        }
        else if(numerator<0)
        {
            op = false;
            num1 = -num1;
        }
        else if(num2<0)
        {
            op = false;
            num2 = -num2;
        }
        string ans = "";
        int f1,f2;
        if(num1<num2) ans += "0";
        else
        {
            f1 = num1/num2;
            ans += to_string(f1);
            num1 -= f1*num2;
        }
        ans += ".";
        map<int,int> mp;
        while(num1*10<num2)
        {
            mp[num1] = ans.size();
            ans += "0";
            num1 *= 10;
        }
        bool circle = false; // 是否是循环小数
        mp[num1] = ans.size();
        int st,en;
        while(num1)
        {
            num1 *= 10;
            f1 = num1/num2; //商
            f2 = num1%num2; //余数
            if(mp[f2])
            {
                ans += to_string(f1);
                st = mp[f2];
                en = ans.size()-1;
                circle = true;
                break;
            }
            if(f2==0)
            {
                ans += to_string(f1);
                break;
            }
            ans += to_string(f1);
            mp[f2] = ans.size();
            num1 = f2;
        }
        if(!circle)
        {
            if(!op)
            {
                string temp = "-";
                temp += ans;
                return temp;
            }
            else return ans;
        }
        else
        {
            int start = ans.find('.');
            string temp = ans.substr(0,start+1);
            for(int i = start+1; i<st;i++ ) temp += ans[i];
            temp += "(";
            temp += ans.substr(st,ans.size()-st);
            temp += ")";
            if(!op)
            {
                string temp1  = "-";
                temp1 += temp;
                return temp1;
            }
            else return temp;
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值