forked from ely-mitu/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fractionToRecurringDecimal.cpp
128 lines (112 loc) · 3.19 KB
/
fractionToRecurringDecimal.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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>
#include <map>
using namespace std;
/*
* 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"; }
//using long long type make sure there has no integer overflow
long long n = numerator;
long long d = denominator;
//deal with negtive cases
bool sign = ((float)numerator/denominator >= 0);
if ( n < 0 ){ n = -n; }
if ( d < 0 ){ d = -d; }
if (sign == false){
result.push_back('-');
}
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('.');
//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 )
map<long long, int> rec;
for (int pos=result.size(); remainder!=0; pos++, remainder=(remainder*10)%d ) {
if (rec.find(remainder) != rec.end()) {
result.insert(result.begin()+rec[remainder], '(');
result.push_back(')');
return result;
}
rec[remainder] = pos;
result.push_back((remainder*10)/d + '0');
}
return result;
}
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;
}