I used a simulation method, tried my best and finally succeeded. There are too many special cases. It’s best to use gdb to debug step by step to find the parts not considered in the code and then improve. Note: do not divide by the greatest common divisor first, because the time complexity of calculating the GCD is higher than that of long division. Also, it’s better to calculate the integer part first, then the decimal part. My solution did not consider this, making the code a bit complicated.
using std::string; using std::unordered_map; using std::vector;
classSolution { public: string fractionToDecimal(int numerator, int denominator){
unsignedlonglong dividend; unsignedlonglong divisor; unsignedlonglong quotient; unsignedlonglong reminder; int dot = -1; int bracket = -1; // Record result vector<int> res_vec; // Record each digit of numerator vector<int> numerator_vec; // Record all dividends unordered_map<unsignedlonglong, unsignedlonglong> div_map; string res; int i = 0; int n; bool negative = false;
// 0 divided by any number is 0 if (numerator == 0) { return"0"; } if ((numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0)) { negative = true; } // The main reason for not using abs is that abs returns an unsigned int, which has range issues. dividend = std::llabs((longlong)numerator); divisor = std::llabs((longlong)denominator);
// First divide both by the greatest common factor. // n = std::gcd(dividend, divisor); // dividend /= n; // divisor /= n;
// Put each digit of the numerator into numerator_vec. while (dividend != 0) { numerator_vec.insert(numerator_vec.begin(), dividend % 10); dividend /= 10; } dividend = 0; // High-precision division.
// First dividend. n = numerator_vec.size(); while (i < n && dividend < divisor) { dividend = dividend * 10 + numerator_vec[i]; i++; }
The official method also simulates long division, but the difference is that I recorded the dividend, while this solution records the remainder to determine if a repeating decimal occurs.