题目地址
https://leetcode-cn.com/problems/fraction-to-recurring-decimal/
题目描述:分数到小数
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
示例:
例 1:
输入: numerator = 1, denominator = 2
输出: “0.5”
例 2:
输入: numerator = 2, denominator = 1
输出: “2”
例 3:
输入: numerator = 2, denominator = 3
输出: “0.(6)”
解答
阅读理解题,但有一点非常关键:如何标记无限循环小数的括号位置?
若存在无限不循环小数,则新一轮循环开始时,除数(即num1)已经出现过。据此,可以利用 map, 将所有的除数存储起来,若出现重复的除数,则标记相应的位置为括号起始位。
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
if( numerator == 0)
return "0";
string res = "";
int flagNegative = (numerator ^ denominator) & 0x80000000; //处理符号位,方便处理负数
//防止溢出,将int转化为long
long num1 = abs((long)numerator), num2 = abs((long)denominator);
//处理小数点前面一部分
res += to_string(num1 /num2), num1 %= num2;
if( num1 == 0){
if( flagNegative)
res = '-' + res;
return res;
}
res += '.';
unordered_map<int,int> record;
int flagPos = -1; //标记应该加括号的位置
//处理小数部分
while( num1 != 0){
if( record.count(num1)){
flagPos = record[num1];
break;
}
record[num1] = res.size();
num1 *= 10, res += to_string(num1 /num2), num1 %= num2;
}
//若没有循环小数
if( num1 == 0){
if( flagNegative)
res = '-' + res;
return res;
}
//若有循环小数
//加括号
res.insert(res.begin() + flagPos, '('), res+=')';
if( flagNegative)
res = '-' + res;
return res;
}
};