题目:
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
示例 1:
输入: numerator = 1, denominator = 2 输出: "0.5"
示例 2:
输入: numerator = 2, denominator = 1 输出: "2"
示例 3:
输入: numerator = 2, denominator = 3 输出: "0.(6)"
思路:在网上百度了大神的代码,原文链接如下:https://blog.youkuaiyun.com/zdavb/article/details/47836081
在这段代码中用到了几种数据结构:Hashmap中用来存储每次的除数和它对应的商在数组中的位置;StringBuilder用来存放最后商的字符表示;List用来存放商的数字表示。index用来表示循环前小数的位数,beginindex用来表示开始循环的小数。
要注意的点有:
(1)每次相除的时候保存商,求出余数,余数乘10再接着除以被除数。将每一次的除数存放在hahmap中,一旦有相同的除数出现表示循环开始
(2)为了防止溢出,将数据类型由int转变为long
代码:
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
HashMap<Long,Integer> maps = new HashMap<>();
StringBuilder sb=new StringBuilder();
List<Long> number = new ArrayList<>();
int beginindex=-1;
int index=0;
if(denominator==0)//判断除数是否为0
return "";
long num=numerator; //转变为大的数据类型,防止溢出
long denom=denominator;
if((num<0&&denom>0)||(num>0&&denom<0))//首先判断正负号
sb.append('-');
num=Math.abs(num); //取绝对值
denom=Math.abs(denom);
long val=num/denom;//这个应该放在取绝对值之后,放在之前会出错
sb.append(String.valueOf(val)); //将in值转化为String
num=(num%denom)*10;
while(num!=0){
if(maps.containsKey(num)) //出现相同除数,结束循环
{
beginindex=maps.get(num);
break;
}
else
{
maps.put(num,index++);
val=num/denom;
num=(num%denom)*10;
number.add(val);
}
}
for(int i=0;i<index;i++){
if(i==0)
sb.append('.');
if(i==beginindex)
sb.append('(');
sb.append(number.get(i));
}
if(beginindex!=-1)
sb.append(')');
return sb.toString(); //注意最后的toString
}
}