相等的有理数

相等的有理数

#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);
	}
};

有理数

发布了40 篇原创文章 · 获赞 6 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/mrbaolong/article/details/104411263
今日推荐