Given two strings s and t, each of which represents a non-negative rational number, return true if and only if they represent the same number.
The strings may use parentheses to denote the repeating part of the rational number.
A rational number can be represented using up to three parts:
<IntegerPart>, <NonRepeatingPart>, and a <RepeatingPart>. The number will be represented in one of the following three ways:
Input: s ="0.(52)", t ="0.5(25)"Output: trueExplanation: Because "0.(52)" represents 0.52525252..., and "0.5(25)" represents 0.52525252525....., the strings represent the same number.
Input: s ="0.9(9)", t ="1."Output: trueExplanation: "0.9(9)" represents 0.999999999... repeated forever, which equals 1.[[See this link for an explanation.](https://en.wikipedia.org/wiki/0.999...)]
"1." represents the number 1, which is formed correctly:(IntegerPart)="1" and (NonRepeatingPart)="".
To check if two rational numbers with possible repeating decimals are equal, convert each to a canonical fraction (numerator/denominator) and compare. This handles all forms, including repeating decimals, by using the formula for the sum of a repeating decimal.
classSolution {
publicbooleanisRationalEqual(String s, String t) {
return parse(s).equals(parse(t));
}
private Fraction parse(String str) {
int i = str.indexOf('.'), j = str.indexOf('(');
String intp = i ==-1 ? str : str.substring(0, i);
String nonrep = i ==-1 ?"" : (j ==-1 ? str.substring(i+1) : str.substring(i+1, j));
String rep = j ==-1 ?"" : str.substring(j+1, str.length()-1);
long num = Long.parseLong(intp), den = 1;
if (!nonrep.isEmpty()) {
num = num * pow10(nonrep.length()) + Long.parseLong(nonrep);
den *= pow10(nonrep.length());
}
if (!rep.isEmpty()) {
long repnum = Long.parseLong(rep);
int rep_len = rep.length();
long repden = pow10(rep_len) - 1;
num = num * repden + repnum;
den *= repden;
}
long g = gcd(num, den);
returnnew Fraction(num/g, den/g);
}
privatelongpow10(int n) {
long res = 1;
for (int i = 0; i < n; i++) res *= 10;
return res;
}
privatelonggcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
privatestaticclassFraction {
long num, den;
Fraction(long n, long d) { num = n; den = d; }
publicbooleanequals(Object o) {
if (!(o instanceof Fraction)) returnfalse;
Fraction f = (Fraction)o;
return num == f.num&& den == f.den;
}
publicinthashCode() { return Long.hashCode(num) ^ Long.hashCode(den); }
}
}
classSolution {
funisRationalEqual(s: String, t: String): Boolean {
funparse(str: String): Pair<Long, Long> {
val i = str.indexOf('.')
val j = str.indexOf('(')
val intp = if (i == -1) str else str.substring(0, i)
val nonrep = if (i == -1) ""elseif (j == -1) str.substring(i+1) else str.substring(i+1, j)
val rep = if (j == -1) ""else str.substring(j+1, str.length-1)
var num = intp.toLong()
var den = 1Lif (nonrep.isNotEmpty()) {
num = num * 10.0.pow(nonrep.length).toLong() + nonrep.toLong()
den *=10.0.pow(nonrep.length).toLong()
}
if (rep.isNotEmpty()) {
val repnum = rep.toLong()
val repden = 10.0.pow(rep.length).toLong() - 1 num = num * repden + repnum
den *= repden
}
val g = gcd(num, den)
return num/g to den/g
}
fungcd(a: Long, b: Long): Long = if (b ==0L) a else gcd(b, a % b)
return parse(s) == parse(t)
}
}