[Lc]166分数到小数
Contents
题目
题解
这道题其实就是模拟笔算除法的过程,挨个位产生商,主要判断是否除尽或者产生了循环。
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string res;
if(numerator==0) return "0";
//用异或判断是否为负
if((numerator<0)^(denominator<0)) res.push_back('-');
auto n = static_cast<long long>(numerator);
auto d = static_cast<long long>(denominator);//转为longlong防止溢出
n = llabs(n);
d = llabs(d);//取绝对值
res.append(to_string(n/d));//先添加整数部分
auto v = n%d;//取余数
if(v==0) return res;//余数为0,直接返回
//不为0,继续下面的操作
res.push_back('.');//在res后加上小数点
//index存小数点之后的位置,用于map存每个余数的商所在的位置,用于后续在其之前添加'('
int index = res.size();
//注意!虽然无限循环小数的商循环,但是有可能出现一个循环内多个相同的数字
//因此在判断时要判断被除数是否产生了循环,若产生了则证明有循环
unordered_map<long long, int> m;//map存余数(即被除数)及其下标
while(v!=0 && m.count(v)==0){//v没别除尽或者没有产生循环
m[v] = index++;//存当前的余数(即被除数),和其下标,要先存在乘10,否则会死循环
v *= 10;//余数乘10
res.append(to_string(v/d));//res加入这个商的整数部分
v %= d;//v取余
}
//跳出while循环说明有循环,找到循环的第一数字,在之前加'(',在res最后加')'
//注意这里必须加判断,上一步有可能是除尽跳出循环,就不需要加括号
if(m.count(v)==1){
res.insert(m[v],"(");
res.push_back(')');
}
return res;
}
Author ChrisHRZ
LastMod 2020-05-08