2014-12-16 22:58:13 +08:00
|
|
|
// Source : https://oj.leetcode.com/problems/fraction-to-recurring-decimal/
|
|
|
|
// Author : Hao Chen
|
|
|
|
// Date : 2014-12-16
|
|
|
|
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
|
|
|
|
*
|
|
|
|
* If the fractional part is repeating, enclose the repeating part in parentheses.
|
|
|
|
*
|
|
|
|
* For example,
|
|
|
|
*
|
|
|
|
* Given numerator = 1, denominator = 2, return "0.5".
|
|
|
|
* Given numerator = 2, denominator = 1, return "2".
|
|
|
|
* Given numerator = 2, denominator = 3, return "0.(6)".
|
|
|
|
*
|
|
|
|
* Credits:Special thanks to @Shangrila for adding this problem and creating all test cases.
|
|
|
|
*
|
|
|
|
**********************************************************************************/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
2014-12-17 14:04:34 +08:00
|
|
|
#include <map>
|
2014-12-16 22:58:13 +08:00
|
|
|
using namespace std;
|
|
|
|
|
2014-12-17 14:04:34 +08:00
|
|
|
|
2014-12-16 22:58:13 +08:00
|
|
|
/*
|
|
|
|
* Be careful the following cases:
|
|
|
|
*
|
|
|
|
* > 0/2
|
|
|
|
* > 1/0
|
|
|
|
* > 1/3
|
|
|
|
* > 2/4
|
|
|
|
* > 100/2
|
|
|
|
* > 100/3
|
|
|
|
* > 1/-4
|
|
|
|
* > -1/4
|
|
|
|
* > -1/-4
|
|
|
|
* > 25/99 = 0.25252525....
|
|
|
|
* > 1/7 = 0.142857142857...
|
|
|
|
* > 1/17 = 0.(0588235294117647)
|
|
|
|
*/
|
|
|
|
|
|
|
|
string fractionToDecimal(int numerator, int denominator) {
|
|
|
|
string result;
|
|
|
|
//deal with the `ZERO` cases
|
|
|
|
if (denominator == 0){ return result; }
|
|
|
|
if (numerator == 0) { return "0"; }
|
2014-12-17 14:04:34 +08:00
|
|
|
|
2014-12-16 22:58:13 +08:00
|
|
|
//using long long type make sure there has no integer overflow
|
|
|
|
long long n = numerator;
|
|
|
|
long long d = denominator;
|
|
|
|
|
|
|
|
//deal with negtive cases
|
2014-12-17 14:04:34 +08:00
|
|
|
bool sign = ((float)numerator/denominator >= 0);
|
|
|
|
if ( n < 0 ){ n = -n; }
|
|
|
|
if ( d < 0 ){ d = -d; }
|
|
|
|
if (sign == false){
|
2014-12-16 22:58:13 +08:00
|
|
|
result.push_back('-');
|
|
|
|
}
|
|
|
|
|
2014-12-17 14:04:34 +08:00
|
|
|
long long remainder = n % d;
|
|
|
|
long long division = n / d;
|
|
|
|
ostringstream oss;
|
|
|
|
oss << division;
|
|
|
|
result += oss.str();
|
|
|
|
if (remainder == 0){
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
//remainder has value, the result is a float
|
|
|
|
result.push_back('.');
|
2014-12-16 22:58:13 +08:00
|
|
|
|
2014-12-17 14:08:08 +08:00
|
|
|
//using a map to record all of reminders and their position.
|
|
|
|
//if the reminder appeared before, which means the repeated loop begin,
|
|
|
|
//then, get the place from map to insert "(".
|
|
|
|
//(In C++11, it's better to use unordered_map )
|
2014-12-17 14:04:34 +08:00
|
|
|
map<long long, int> rec;
|
2014-12-16 22:58:13 +08:00
|
|
|
|
2014-12-17 14:04:34 +08:00
|
|
|
for (int pos=result.size(); remainder!=0; pos++, remainder=(remainder*10)%d ) {
|
|
|
|
if (rec.find(remainder) != rec.end()) {
|
|
|
|
result.insert(result.begin()+rec[remainder], '(');
|
2014-12-16 22:58:13 +08:00
|
|
|
result.push_back(')');
|
2014-12-17 14:04:34 +08:00
|
|
|
return result;
|
2014-12-16 22:58:13 +08:00
|
|
|
}
|
2014-12-17 14:04:34 +08:00
|
|
|
rec[remainder] = pos;
|
|
|
|
result.push_back((remainder*10)/d + '0');
|
2014-12-16 22:58:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2014-12-17 14:04:34 +08:00
|
|
|
|
2014-12-16 22:58:13 +08:00
|
|
|
void test(int num, int deno)
|
|
|
|
{
|
|
|
|
cout << "numerator: " << num << "\tdenominator: " << deno << "\tresult: " << fractionToDecimal(num, deno) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
test(1, 2);
|
|
|
|
test(10, 2);
|
|
|
|
test(100, 2);
|
|
|
|
test(1, 3);
|
|
|
|
test(100, 3);
|
|
|
|
test(1, 6);
|
|
|
|
test(100, 6);
|
|
|
|
test(-1, 4);
|
|
|
|
test(1, -3);
|
|
|
|
test(-1, -6);
|
|
|
|
test(25, 99);
|
|
|
|
test(1, 7);
|
|
|
|
test(10, 7);
|
|
|
|
test(100, 7);
|
|
|
|
test(1, 17);
|
|
|
|
test(1, 1024);
|
|
|
|
test( -2147483648, -1999);
|
|
|
|
test(-1, -2147483648);
|
|
|
|
|
|
|
|
|
|
|
|
if (argc > 2) {
|
|
|
|
int num = atoi(argv[1]);
|
|
|
|
int deno = atoi(argv[2]);
|
|
|
|
test(num, deno);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|