題目
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.
For example,
- Given numerator = 1, denominator = 2, return "0.5".
- Given numerator = 2, denominator = 1, return "2".
- Given numerator = 2, denominator = 3, return "0.(6)".
計算整數除法,要求循環的小數位用括號括起來,最初打算保存小數,並利用int [10]的數組保存每個值出現的位置,有重複則說明循環,加入括號即可,但是發現有些情況,比如1/333,會出現0.003003的循環,因此小數的循環不是根據商的重複出現而定,而是餘數的重複出現決定的,參考0ms C++ Solution with Detailed Explanations 的思想進行修改,利用map保存<餘數,下標>,當餘數重複出現時,只需在上次出現位置之前插入左括號,在當前末尾加入右括號即可。
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
long num=numerator, den=denominator;
string res;
if(!num)
return "0";
if(num<0^den<0)//如果num和den其中一個爲負數,則需要在結果前面加上負號
res+="-";
num=num<0?num*=-1:num;//將負值轉換成正數
den=den<0?den*=-1:den;
long inter=num/den;//保存整數部分
res+=to_string(inter);//結果加入整數部分
num=num%den;//根據餘數計算小數部分的除法
if(!num)//餘數爲0則整除,直接返回
return res;
res+=".";//否則加入小數點並餘數*10進行借位除法
num*=10;
unordered_map<long,long> map;//用map保存小數除法中的被除數,循環的條件是出現重複的被除數而不是通過重複的商判斷
while(num){
long temp=num/den;
if(map.find(num)!=map.end()){//如果出現了重複的被除數,則下一步一定會循環,所以在上次被除數出現的位置之前插入左括號(,並在末尾插入右括號)
res.insert(map[num],1,'(');
res+=")";
return res;
}
map[num]=res.size();//被除數不重複時,令map保存當前被除數的商在res中的下標位置,由於res還未壓入商,故該下標位置爲res.size()
res+=to_string(temp);
num%=den;//取餘數,乘10,繼續除法運算
num*=10;
}
return res;
}
};