分数到小数
先说说几种可能出错的情况。
- 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;
}
};