#include <string>
using namespace std;
class Solution {
public:
using ll = long long;
// 寻找n, m的最大公约数,辗转相除法 n<m
ll gcd(ll n, ll m) {
if (n > m) return gcd(m, n);
if (n == 0 || m % n == 0) return n;
return gcd(m % n, n);
}
// 化简分数 n / m
void simplify(ll& n, ll& m) {
if (n == 0 || m == 0) {
n = 0;
m = 1;
}
ll t = gcd(n, m);
if (t > 0) {
n /= t;
m /= t;
}
}
// 两分数相加 n1 / d1 + n2 / d2;
pair<ll, ll> add(ll n1, ll d1, ll n2, ll d2) {
ll n, d;
if (d1 == 0) {
n = n2;
d = d2;
}
else if (d2 == 0) {
n = n1;
d = d1;
}
else {
n = n1 * d2 + n2 * d1;
d = d1 * d2;
}
simplify(n, d);
return { n, d };//pair<int,int>
}
//转换成分数
pair<int, int> trans(string S) {
ll int_part = 0;
ll nonrep_part = 0;
ll rep_part = 0;
ll nonrep_len = 0;
ll rep_len = 0;
int i = 0;
int N = S.size();
while (i < N && S[i] != '.') {
int_part = int_part * 10 + S[i] - '0';//S[i] - '0' 字符转换为数值
++i;
}
++i;//跳过 '.'
while (i < N && S[i] != '(') {
nonrep_part = nonrep_part * 10 + S[i] - '0';
++nonrep_len;
++i;
}
++i;//跳过 '('
while (i < N && S[i] != ')') {
rep_part = rep_part * 10 + S[i] - '0';
++rep_len;
++i;
}
ll p1 = pow(10, nonrep_len);
ll p2 = pow(10, rep_len);
ll p3 = p1 * p2;
// 非重复小数部分的分子与分母:转化为frac/100
ll nonrep_num = nonrep_part;
ll nonrep_dom = p1;
// 重复小数部分的分子与分母:x/100+x/10000+......
ll rep_num = rep_part * p2;
ll rep_dom = p3 * (p2 - 1);
simplify(nonrep_num, nonrep_dom);
simplify(rep_num, rep_dom);
auto p = add(nonrep_num, nonrep_dom, rep_num, rep_dom);
return add(p.first, p.second, int_part, 1LL);
}
bool isRationalEqual(string S, string T) {
return trans(S) == trans(T);
}
};
相等的有理数
最新推荐文章于 2022-05-12 15:08:52 发布