Skip to content

Commit 47fa067

Browse files
authored
Create Source.cpp
1 parent 6a99ce9 commit 47fa067

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed

FractionKeyboardInput/Source.cpp

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
#include <iostream>
2+
#include <iomanip>
3+
#include <sstream>
4+
#include <ctime>
5+
#include <vector>
6+
#include <tuple>
7+
#include <regex>
8+
#include <fstream>
9+
#include <string>
10+
using namespace std;
11+
12+
class Integer;
13+
class Fraction;
14+
class FractionToLowestTermUIConverter;
15+
class RandomIntegerGenerator;
16+
class RandomFractionGenerator;
17+
class FractionToStringDataConverter;
18+
class FractionDataReader;
19+
20+
class Integer {
21+
public:
22+
static int gcd(int a, int b) {
23+
if (a == 0) return b;
24+
if (b == 0) return a;
25+
if (a == b) return a;
26+
if (a > b) return gcd(a - b, b);
27+
return gcd(a, b - a);
28+
}
29+
};
30+
31+
// Class: Fraction
32+
// Description: This class is used to represent a fraction
33+
class Fraction {
34+
private:
35+
long long _num;
36+
long long _den;
37+
public:
38+
long long Numerator() const { return _num; }
39+
long long Denominator() const { return _den; }
40+
41+
void setNum(long long num) { _num = num; }
42+
void setDen(long long den) { _den = den; }
43+
44+
Fraction() { _num = 0; _den = 1; }
45+
Fraction(long long num, long long den) { _num = num; _den = den; }
46+
47+
static Fraction sumTwoFractions(const Fraction& a, const Fraction& b) {
48+
Fraction sum;
49+
50+
sum.setNum(a.Denominator() * b.Numerator() + a.Numerator() * b.Denominator());
51+
sum.setDen(a.Denominator() * b.Denominator());
52+
long long gcd = Integer::gcd(sum.Numerator(), sum.Denominator());
53+
sum.setNum(sum.Numerator() / gcd);
54+
sum.setDen(sum.Denominator() / gcd);
55+
return sum;
56+
}
57+
};
58+
59+
60+
class RandomIntegerGenerator {
61+
public:
62+
RandomIntegerGenerator() {
63+
srand(time(NULL));
64+
}
65+
int next() { return rand(); }
66+
int next(int ceiling) { return rand() % ceiling; }
67+
int next(int left, int right) { return rand() % (right - left + 1) + left; }
68+
};
69+
70+
class FractionToLowestTermUIConverter {
71+
public:
72+
string Convert(const Fraction& f) {
73+
stringstream ss;
74+
long long gcd = Integer::gcd(f.Numerator(), f.Denominator());
75+
long long num = f.Numerator() / gcd;
76+
long long den = f.Denominator() / gcd;
77+
78+
if (num > den) {
79+
long long fullNum = num / den;
80+
ss << fullNum << " ";
81+
num = num % den;
82+
}
83+
84+
if (num > 0) {
85+
ss << num;
86+
if (den != 1) ss << "/" << den;
87+
}
88+
89+
string ans = ss.str();
90+
return ans;
91+
}
92+
};
93+
94+
class FractionToStringUIConverter {
95+
public:
96+
bool isValidFormat(string value) {
97+
bool isValid = true;
98+
//
99+
const string patterns = "\\b\\d+\\/[1-9][0-9]*\\b";
100+
const string patterns2 = "\\b\\d+\\b";
101+
const string patterns3 = "\\b\\d+\\s\\d+\\/[1-9][0-9]*\\b";
102+
regex fractionsFormat(patterns);
103+
regex fractionsFormat2(patterns2);
104+
regex fractionsFormat3(patterns3);
105+
if (!regex_match(value, fractionsFormat) && !regex_match(value, fractionsFormat2) && !regex_match(value, fractionsFormat3)) {
106+
isValid = false;
107+
}
108+
return isValid;
109+
}
110+
111+
string convert(const Fraction& f) {
112+
stringstream ss;
113+
ss << f.Numerator() << "/" << f.Denominator();
114+
string ans = ss.str();
115+
return ans;
116+
}
117+
118+
Fraction convertBack(string value) {
119+
bool isValid = isValidFormat(value);
120+
Fraction f;
121+
if (isValid) {
122+
int slash = value.find('/');
123+
int space = value.find(' ');
124+
125+
if (slash == -1 && space == -1) {
126+
f.setNum(stoi(value));
127+
f.setDen(1);
128+
}
129+
if (space == -1) {
130+
string n = value.substr(0, slash);
131+
string d = value.substr(slash + 1);
132+
f.setNum(stoi(n));
133+
f.setDen(stoi(d));
134+
}
135+
else {
136+
string n2 = value.substr(0, space);
137+
string d2 = value.substr(space + 1, slash - space - 1);
138+
string a = value.substr(slash + 1);
139+
f.setNum(stoi(n2) * stoi(a) + stoi(d2));
140+
f.setDen(stoi(a));
141+
}
142+
}
143+
else {
144+
throw runtime_error("Wrong format, please try again");
145+
}
146+
}
147+
148+
bool tryConvertBack(string buffer, Fraction& f) {
149+
bool result = true;
150+
bool isValid = isValidFormat(buffer);
151+
if (isValid) { f = convertBack(buffer); }
152+
else { result = false; }
153+
return result;
154+
}
155+
};
156+
157+
158+
159+
class FractionDataReader {
160+
private:
161+
string _connectingString;
162+
public:
163+
FractionDataReader(string connectingString) {
164+
_connectingString = connectingString;
165+
}
166+
167+
vector<Fraction>GetAll() {
168+
ifstream input(_connectingString);
169+
vector<Fraction> f;
170+
171+
while (!input.eof()) {
172+
string line;
173+
getline(input, line);
174+
Fraction a;
175+
bool checkOK;
176+
FractionToStringUIConverter fConvert;
177+
try {
178+
checkOK = fConvert.tryConvertBack(line, a);
179+
}
180+
catch (runtime_error e) {
181+
checkOK = false;
182+
cout << e.what() << endl;
183+
}
184+
if (checkOK) {
185+
f.push_back(a);
186+
}
187+
}
188+
input.close();
189+
return f;
190+
}
191+
};
192+
193+
class FractionDataWriter {
194+
private:
195+
string _connectingString;
196+
public:
197+
FractionDataWriter(string connectingString) {
198+
_connectingString = connectingString;
199+
}
200+
201+
void Write(const Fraction& f) {
202+
ofstream output(_connectingString, ios::app);
203+
FractionToStringUIConverter fConvert;
204+
string line = fConvert.convert(f);
205+
output << line << endl;
206+
output.close();
207+
}
208+
};
209+
210+
int main() {
211+
vector<Fraction> a;
212+
string s;
213+
RandomIntegerGenerator r;
214+
FractionToStringUIConverter converter;
215+
FractionDataWriter writer("data.txt");
216+
Fraction f;
217+
int n = r.next(5, 10);
218+
cout << "Please input " << n << " fractions" << endl;
219+
// Input n fractions from user and check if they are valid, if not, ask user to input again and
220+
// write them to file
221+
for (int i = 0; i < n; i++) {
222+
cout << "Please input fraction " << i + 1 << ": ";
223+
getline(cin, s);
224+
bool checkOK;
225+
try {
226+
checkOK = converter.tryConvertBack(s, f);
227+
}
228+
catch (runtime_error e) {
229+
checkOK = false;
230+
cout << e.what() << endl;
231+
}
232+
if (checkOK) {
233+
a.push_back(f);
234+
writer.Write(f);
235+
}
236+
else {
237+
i--;
238+
}
239+
}
240+
241+
Fraction sum;
242+
FractionToLowestTermUIConverter fLowConvert;
243+
244+
for (int i = 0; i < a.size(); i++) {
245+
sum = sum.sumTwoFractions(sum, a[i]);
246+
}
247+
cout << "The total is: " << fLowConvert.Convert(sum) << endl;
248+
}

0 commit comments

Comments
 (0)