【算法训练】LeetCode#166 分数到小数
一、描述
166. 分数到小数
给定两个整数,分别表示分数的分子 numerator
和分母 denominator
,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104
。
示例 1:
输入:numerator = 1, denominator = 2
输出:"0.5"
示例 2:
输入:numerator = 2, denominator = 1
输出:"2"
示例 3:
输入:numerator = 4, denominator = 333
输出:"0.(012)"
二、思路
不太明白这道题考察的什么,先做一做。
感觉直接double求结果再转string判断循环体是不是可以呢。
不可以....明白了,主要考查点就是判断循环体是哪部分,如果直接得到结果,就没办法知道循环体了。需要模拟除法过程。
三、解题
public class LeetCode166 {
public static String fractionToDecimal(int numerator, int denominator) {
long a = numerator;
long b = denominator;
StringBuilder ans = new StringBuilder();
if ((a>0 && b<0) || (a<0 && b>0)) ans.append('-'); // 如果异号则结果为负
a = Math.abs(a);
b = Math.abs(b);
ans.append(a/b); // 加入整数部分
if (a%b == 0 ) return ans.toString(); // 如果整除了,则直接返回
ans.append('.'); // 不整除加小数点
a = a%b;
HashMap<Long,Integer> map = new HashMap<>(); // 记录被除数以及出现的位置
map.put(a,ans.length()); // 每一次插入的位置都是字符串当前长度
long flag = 0;
while (a != 0){
a *= 10;
long next = a/b;
ans.append(next);
a = a-next*b; // 得到余数作为新的a
if (map.containsKey(a)){
// 如果存在,则证明循环小数
int Loc = map.get(a); // 得到第一次出现的位置
ans.insert(Loc,"("); // 插入
ans.append(")");
break;
}
map.put(a,ans.length());
}
return ans.toString();
}
public static void main(String[] args) {
System.out.println(fractionToDecimal(1,333));
}
}