指尖劃過的軌跡,藏着最細膩的答案~
題目:
給定兩個整數,分別表示分數的分子 numerator 和分母 denominator,以 字符串形式返回小數 。
如果小數部分為循環小數,則將循環的部分括在括號內。
如果存在多個答案,只需返回 任意一個 。
對於所有給定的輸入,保證 答案字符串的長度小於 $10^4$ 。
示例 1:
輸入:
numerator = 1, denominator = 2
輸出:"0.5"
示例 2:
輸入:
numerator = 2, denominator = 1
輸出:"2"
示例 3:
輸入:
numerator = 4, denominator = 333
輸出:"0.(012)"
提示:
- $-2^{31} \leq numerator, denominator \leq 2^{31} - 1$
- $denominator \neq 0$
分析:
本題我們首先需要模擬長除法即可,假設商為q,餘數為r,則除法運算如下:$\frac{a}{b} = q...r$,將q拼接如答案,接下來將$\frac{r * 10}{b} = q...r1, r = r1$,根據上面公式,直到:
r == 0表示除盡;- 循環小數:怎樣判斷循環部分呢,我們可以使用哈希表來記錄,
key為r,value為下標,在再次出現r時,説明有循環,將r_to_pos[r]到當前下標使用括號括起來。
AC代碼:
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
long long a = numerator, b = denominator;
string sign = a * b < 0 ? "-" : "";
a = abs(a);
b = abs(b);
long long q = a / b, r = a % b;
if (r == 0) {
return sign + to_string(q);
}
string ans = sign + to_string(q) + ".";
unordered_map<long long, int> r_to_pos = {{r, ans.size()}};
while(r) {
r *= 10;
q = r / b;
r %= b;
ans += '0' + q;
if (r_to_pos.contains(r)) {
int poc = r_to_pos[r];
return ans.substr(0, poc) + "(" + ans.substr(poc) + ")";
}
r_to_pos[r] = ans.size();
}
return ans;
}
};