問題是將一個小數表示成一個分數。當然,只有有限小數和無限循環小數才能轉換爲分數。
對於無限循環小數,給定的格式是將循環節用括號括起來,比如: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;
}
執行結果: