返回
算法题解——LeetCode每日一题|166. 分数到小数
前端
2023-09-30 12:42:18
对于分数到小数的转换,很多同学第一想到的可能是长除法。虽然长除法是一个直接的方法,但我们也可以用更加巧妙的数学方法来解决这个问题。
思路分析
首先,我们需要检查分子和分母是否有公约数。如果有,那么我们可以先约分,这样可以减少计算量。
接下来,我们需要将分子除以分母,得到一个整数部分和一个余数。整数部分就是小数点前面的部分,余数就是小数点后面的部分。
如果余数为0,那么小数部分就结束了。否则,我们将余数乘以10,然后继续除以分母。这样,我们就可以得到小数部分的下一位数字。
重复这个过程,直到余数为0,或者小数部分达到我们想要的精度。
输出结果
输出结果分为三个部分:符号、整数、小数。
- 符号:如果分子和分母异号,那么符号为负号;否则,符号为正号。
- 整数:整数部分就是分子除以分母得到的整数部分。
- 小数:小数部分就是余数不断除以分母得到的结果。
编程实现
以下是Python、Java、C++、Javascript等多种编程语言的解题代码:
Python代码:
def fractionToDecimal(numerator, denominator):
"""
:type numerator: int
:type denominator: int
:rtype: str
"""
# 检查分子和分母是否有公约数
gcd = math.gcd(numerator, denominator)
if gcd > 1:
numerator //= gcd
denominator //= gcd
# 计算整数部分
integer_part = numerator // denominator
# 计算余数
remainder = numerator % denominator
# 如果余数为0,那么小数部分就结束了
if remainder == 0:
return str(integer_part)
# 将余数乘以10,然后继续除以分母
decimal_part = ""
seen = set()
while remainder != 0 and remainder not in seen:
seen.add(remainder)
remainder *= 10
digit = remainder // denominator
remainder %= denominator
decimal_part += str(digit)
# 如果小数部分有循环,那么在循环开始的地方添加括号
if remainder in seen:
index = decimal_part.index(str(remainder))
decimal_part = decimal_part[:index] + "(" + decimal_part[index:] + ")"
# 返回结果
return str(integer_part) + "." + decimal_part
Java代码:
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
// 检查分子和分母是否有公约数
int gcd = Math.gcd(numerator, denominator);
if (gcd > 1) {
numerator /= gcd;
denominator /= gcd;
}
// 计算整数部分
int integerPart = numerator / denominator;
// 计算余数
int remainder = numerator % denominator;
// 如果余数为0,那么小数部分就结束了
if (remainder == 0) {
return String.valueOf(integerPart);
}
// 将余数乘以10,然后继续除以分母
StringBuilder decimalPart = new StringBuilder();
Set<Integer> seen = new HashSet<>();
while (remainder != 0 && !seen.contains(remainder)) {
seen.add(remainder);
remainder *= 10;
int digit = remainder / denominator;
remainder %= denominator;
decimalPart.append(digit);
}
// 如果小数部分有循环,那么在循环开始的地方添加括号
if (remainder != 0) {
int index = decimalPart.indexOf(String.valueOf(remainder));
decimalPart.insert(index, "(");
decimalPart.append(")");
}
// 返回结果
return integerPart + "." + decimalPart.toString();
}
}
C++代码:
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
// 检查分子和分母是否有公约数
int gcd = std::gcd(numerator, denominator);
if (gcd > 1) {
numerator /= gcd;
denominator /= gcd;
}
// 计算整数部分
int integerPart = numerator / denominator;
// 计算余数
int remainder = numerator % denominator;
// 如果余数为0,那么小数部分就结束了
if (remainder == 0) {
return std::to_string(integerPart);
}
// 将余数乘以10,然后继续除以分母
std::string decimalPart;
std::unordered_set<int> seen;
while (remainder != 0 && seen.find(remainder) == seen.end()) {
seen.insert(remainder);
remainder *= 10;
int digit = remainder / denominator;
remainder %= denominator;
decimalPart += std::to_string(digit);
}
// 如果小数部分有循环,那么在循环开始的地方添加括号
if (remainder != 0) {
int index = decimalPart.find(std::to_string(remainder));
decimalPart.insert(index, "(");
decimalPart += ")";
}
// 返回结果
return std::to_string(integerPart) + "." + decimalPart;
}
};
Javascript代码:
/**
* @param {number} numerator
* @param {number} denominator
* @return {string}
*/
const fractionToDecimal = (numerator, denominator) => {
// 检查分子和分母是否有公约数
const gcd = Math.gcd(numerator, denominator);
if (gcd > 1) {
numerator /= gcd;
denominator /= gcd;
}
// 计算整数部分
const integerPart = Math.floor(numerator / denominator);
// 计算余数
let remainder = numerator % denominator;
// 如果余数为0,那么小数部分就结束了
if (remainder === 0) {
return integerPart.toString();
}
// 将余数乘以10,然后继续除以分母
let decimalPart = "";
const seen = new Set();
while (remainder !== 0 && !seen.has(remainder)) {
seen.add(remainder);
remainder *= 10;
const digit = Math.floor(remainder / denominator);
remainder %= denominator;
decimalPart += digit.toString();
}
// 如果小数部分有循环,那么在循环开始的地方添加括号
if (remainder !== 0) {
const index = decimalPart.indexOf(remainder.toString());
decimalPart = decimalPart.substring(0, index) + "(" + decimalPart.substring(index) + ")";
}
// 返回结果
return integerPart + "." + decimalPart;
};
希望本文对您有所帮助。如果您有任何疑问,请随时留言。