1,题目要求
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)”
给定表示分数的分子和分母的两个整数,以字符串格式返回分数。
如果小数部分重复,则将重复部分括在括号中。
2,题目思路
对于这道题,要求将一个分数形式的数字转换为小数字符串的形式。
在分数的计算上,如果分子和分母都是整数,那么,只会有三种结果:
- 整数
- 有限小数
- 无限循环小数
对于无限循环小数,一定是存在一个循环节,即从该位置开始循环。
而如果我们在计算小数位时,只要有商与之前所得到的商一样,那么,上一个相同的数字就是循环节的开始,在这道题的要求中,停止计算,并用括号将它们括起来。
而在循环节的寻找上,我们使用unordered_map来进行小数位数字和位置。
3,代码实现
static auto speedup = [](){
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
//分子为0
if(numerator == 0)
return "0";
//两整数相除,只有三种结果:
//整数、有限小数和无限循环小数
string res = "";
//利用异或来确定符号
if((numerator > 0)^(denominator>0))
res += "-";
//labs:对long型取绝对值
long n = labs(numerator), d = labs(denominator), r = n%d;
res += to_string(n/d);
//正好整除
if(r == 0)
return res;
//没有整除,有小数部分
res += ".";
//定义map,用来记录循环节的位置
unordered_map<long, int> m;
while(r!=0){
if(m.find(r)!=m.end()){//说明当前的商在之前出现过,于是找到了循环节
res.insert(m[r],"(");
res += ")";
return res;
}
//记录当前的商所在字符串的位置,用于之后可能的循环节位置获取
m[r] = res.size();
r *= 10;
res += to_string(r/d);
r %= d;
}
return res;
}
};