问题:
给定两个整数,分别表示分数的分子numerator 和分母 denominator,以 字符串形式返回小数 。如果小数部分为循环小数,则将循环的部分括在括号内。如果存在多个答案,只需返回 任意一个 。对于所有给定的输入,保证 答案字符串的长度小于 104 。
示例 1:
输入:numerator = 1, denominator = 2
输出:"0.5"
示例 2:
输入:numerator = 2, denominator = 1
输出:"2"
示例 3:
输入:numerator = 2, denominator = 3
输出:"0.(6)"
示例 4:
输入:numerator = 4, denominator = 333
输出:"0.(012)"
示例 5:
输入:numerator = 1, denominator = 5
输出:"0.2"
提示:
-231 <= numerator, denominator <= 231 - 1
denominator != 0
解答思路:
以下是使用 Java 实现将分数转换为小数的代码:
public class FractionToDecimal {
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0) {
return "0";
}
StringBuilder sb = new StringBuilder();
if ((numerator < 0) ^ (denominator < 0)) {
sb.append('-');
}
long num = Math.abs((long) numerator);
long den = Math.abs((long) denominator);
sb.append(num / den);
num %= den;
if (num == 0) {
return sb.toString();
}
sb.append('.');
Map<Long, Integer> map = new HashMap<>();
while (num!= 0) {
if (map.containsKey(num)) {
sb.insert(map.get(num), '(');
sb.append(')');
break;
}
map.put(num, sb.length());
num *= 10;
sb.append(num / den);
num %= den;
}
return sb.toString();
}
public static void main(String[] args) {
FractionToDecimal solution = new FractionToDecimal();
System.out.println(solution.fractionToDecimal(1, 2));
System.out.println(solution.fractionToDecimal(2, 1));
System.out.println(solution.fractionToDecimal(2, 3));
System.out.println(solution.fractionToDecimal(4, 333));
System.out.println(solution.fractionToDecimal(1, 5));
}
}
这个算法的基本思路是:
1. 首先处理符号问题,如果分子和分母异号,则结果为负数。
2. 将分子和分母转换为长整型,以避免整数溢出。
3. 计算整数部分,并将其添加到结果字符串中。
4. 如果余数不为 0,则将余数乘以 10,继续计算小数部分。
5. 使用一个哈希表来记录余数出现的位置,如果余数已经出现过,则表示出现了循环小数,将循环部分括在括号内。
6. 重复步骤 4 和 5,直到余数为 0 或者达到指定的精度。
这个算法的时间复杂度为 O(log(n)),其中 n 是分子和分母的绝对值的最大值。空间复杂度为 O(log(n)),用于存储哈希表。
(文章为作者在学习java过程中的一些个人体会总结和借鉴,如有不当、错误的地方,请各位大佬批评指正,定当努力改正,如有侵权请联系作者删帖。)