问题是将一个小数表示成一个分数。当然,只有有限小数和无限循环小数才能转换为分数。
对于无限循环小数,给定的格式是将循环节用括号括起来,比如:0.3333(3333)。
书中先只考虑了0到1的纯小数,然后分有限小数和无限循环小数讨论,书上讲的已经很好理解了,这里就不赘述了,直接上代码吧。
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
typedef pair<unsigned long, pair<unsigned long, unsigned long> > decimal_type;
unsigned long gcd(unsigned long x, unsigned long y)
{
return (!y) ? x : gcd(y, x % y);
}
unsigned int num_cnt(unsigned long data)
{
unsigned int cnt = 0;
while(data) {
data /= 10;
++cnt;
}
return cnt;
}
pair<unsigned long, unsigned long> transform_dot(decimal_type data)
{
unsigned long numerator = 0, denominator = 0;
unsigned long deci = 0, noncir = 0, cir = 0;
deci = data.first;
noncir = data.second.first;
cir = data.second.second;
if(cir == 0) {
numerator = noncir;
denominator = pow(10, num_cnt(noncir));
}
else {
numerator = noncir * (pow(10, num_cnt(cir)) - 1) + cir;
denominator = pow(10, num_cnt(noncir) + num_cnt(cir)) - pow(10, num_cnt(noncir));
}
unsigned long gcd_tmp = gcd(numerator, denominator);
numerator /= gcd_tmp;
denominator /= gcd_tmp;
return make_pair(numerator, denominator);
}
decimal_type get_frac()
{
unsigned long i = 0, j = 0, k = 0;
char ch = 0;
while(cin >> ch && ch != '.') {
i = i * 10 + ch - '0';
}
while(cin >> ch && ch != '(') {
j = j * 10 + ch -'0';
}
if(ch == '(') {
while(cin >> ch && ch != ')') {
k = k * 10 + ch -'0';
}
}
return make_pair(i, make_pair(j, k));
}
int main()
{
decimal_type data = get_frac();
cout << data.first << "." << data.second.first;
if(data.second.second) {
cout << "(" << data.second.second << ")" << endl;
}
pair<unsigned long, unsigned long> fraction = transform_dot(data);
cout << " = " << fraction.first << " / " << fraction.second << endl;
return 0;
}
执行结果: