【LeetCode-數學】分數到小數
阿新 • • 發佈:2020-07-14
題目描述
給定兩個整數,分別表示分數的分子 numerator 和分母 denominator,以字串形式返回小數。
如果小數部分為迴圈小數,則將迴圈的部分括在括號內。
示例:
輸入: numerator = 1, denominator = 2
輸出: "0.5"
輸入: numerator = 2, denominator = 3
輸出: "0.(6)"
題目連結: https://leetcode-cn.com/problems/fraction-to-recurring-decimal/
思路
模擬人做除法的情況。假設 c = a / b,r = a % b,如果餘數 r 不為 0,則將 r*10 後再次除以 b,如果餘數 r*10%b 不為 0,那麼將 r*10%b 乘以10接著除以 b,如果某一步的餘數為 0,則說明除法結束。如果某一步的餘數在之前出現過,則說明商出現了迴圈
所以,我們使用雜湊表記錄每一步餘數的位置 idx,如果出現了迴圈,則將左括號(
插入到 idx,右括號)
插入到結果的末尾。
程式碼如下:
class Solution { public: string fractionToDecimal(int numerator, int denominator) { if(numerator==0) return "0"; if(denominator==0) return ""; long numer = long(numerator); // 轉為 long,否則會溢位 long denom = long(denominator); string ans = ""; if(numer>0 && denom<0 || numer<0 && denom>0) ans += "-"; //是否同號 numer = abs(numer); // 全轉為正數求解 denom = abs(denom); long a = numer / denom; // a 是當前步的商的整數部分 long r = numer % denom; // r 是當前步的餘數 ans += to_string(a); if(r==0) return ans; unordered_map<int, int> lookup; // 記錄餘數是否出現過 ans += "."; int dotIdx = ans.size()-1; // 小數點出現的位置 while(r && lookup.count(r)==0){ lookup[r] = ++dotIdx; r*=10; ans+=to_string(r/denom); r%=denom; } if(lookup.count(r)==1){ // 餘數在之前出現過,出現迴圈 ans.insert(lookup[r], "("); ans+=")"; } return ans; } };
參考
1、https://leetcode-cn.com/problems/fraction-to-recurring-decimal/solution/cmo-ni-ti-jian-dan-yi-dong-by-xiaoneng/
2、https://leetcode-cn.com/problems/fraction-to-recurring-decimal/solution/fen-shu-dao-xiao-shu-by-leetcode/