分數到小數
先說說幾種可能出錯的情況。
- 0/x 直接輸出0,沒有正負號
- 有負號的情況
- 如果是整除,沒有小數點
- 卡
int
的邊界問題,所以乾脆直接開long long
分析:
大致有兩種情況,整除和出現循環。
於是模擬一下除法的進行。
如:3/7
第一步移位,
3*10 = 30 ,移了一位
第二步整除+取模
30/7=4 … 2
20/7=2 … 6
60/7=8 … 4
40/7=5 … 5
50/7=7 … 1
10/7=1 … 3
30/7 = 4 … 2(已經出現了循環)
找到出現的重複的位置,然後整除的結果就是循環體
4 2 8 5 7 1
注意已經移動了一位
所以最終結果是
0.(428571) (整數部分只有一位,循環體前沒有數字)
小心 1/6這種情況,它的結果是 0.1(6) ;
class Solution {
public:
vector<int> res;
unordered_map<long long,int> vis;
string fractionToDecimal(int numerator, int denominator) {
long long y = denominator;
long long num = numerator;
if(num==0){
return "0";
}
string ans="";
if((num<0)+(y<0)==1){
ans = "-";
}
num = abs(num);
y = abs(y);
long long integer = num/y;
long long x = num%y;
//情況1 整除 如 2/1
if(x==0){
return ans+=to_string(integer);
}
int times = 0;
while(x<y){
x*=10;
times++;
}
//情況2 1/2
if(x%y==0){
ans += to_string(integer)+".";
for(int i=0;i<times-1;i++){
ans+="0";
}
ans+=to_string(x/y);
return ans;
}
//情況3 有限小數 或者 無限不循環小數
ans += to_string(integer)+".";
for(int i=0;i<times-1;i++){
ans+="0";
}
int idx=0;
while(x){
vis[x] = idx++;
res.push_back(x/y);
long long mod = x%y;
if(vis.count(mod*10)){
for(int i=0;i<vis[mod*10];i++){
ans+=to_string(res[i]);
}
ans+="(";
for(int i= vis[mod*10] ;i<res.size();i++){
ans+=to_string(res[i]);
}
ans+=")";
return ans;
}
x = mod*10;
}
for(int i=0;i<res.size();i++){
ans+=to_string(res[i]);
}
return ans;
}
};