标签:
在计算机中,使用float或double来存储小数是不能得到精确值的。如果你希望得到精确计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。比如:
0.9 = 9/10
0.333(3) = 1/3(括号中的数字表示是循环节)
当然一个小数可以用好几种分数形式来表示。如:
0.333(3) = 1/3 = 3/9
给定一个有限小数或无限循环小数,你能否以分母最小的分数形式来返回这个小数呢?如果输入为循环小数,循环节用括号标记出来。下面是一些可能的输入数据,如0.3、0.30、0.3(000)、0.3333(3333)、……
分析与解法
(1) 有限小数情况
如:X=0.a1a2...an
可得10n*X=a1a2...an
则X = a1a2...an/10n
(2) 从第一位开始循环的情况
如Y=0.(b1b2...bm)
则10m*Y=b1b2...bm.(b1b2...bm)=b1b2...bm+Y
则Y=b1b2...bm/(10m-1)
(3) 则一般情况下的循环小数Z=0.a1a2...an(b1b2...bm)
可知10n*Z=a1a2...an+Y=a1a2...an+b1b2...bm/(10m-1)
Z=[(10m-1)a1a2...an+b1b2...bm]/[(10m-1)10n]
最后进行约分即可得到结果。
A/B = (A/(GCD(A, B)))/(B/(GCD(A, B)))
参考代码如下:
1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 using namespace std; 5 6 int gcd(int a, int b) 7 { 8 return (b == 0) ? a : gcd(b, a%b); 9 } 10 11 int tenPow(int n) 12 { 13 int ret = 1; 14 for (int i = 0; i < n; i++) 15 { 16 ret *= 10; 17 } 18 return ret; 19 } 20 21 string intToString(int num) 22 { 23 string ret; 24 if (num == 0) num += ‘0‘; 25 while (num) 26 { 27 ret += num%10 + ‘0‘; 28 num /= 10; 29 } 30 reverse(ret.begin(), ret.end()); 31 return ret; 32 } 33 34 class Fraction 35 { 36 private: 37 int intPart; // 整数部分 38 int decPart; // 循环节前小数部分 39 int cntDec; // 循环节前小数部分的位数 40 bool isCyc; // 是否有循环节 41 int cycPart; // 循环节部分 42 int cntCyc; // 循环节部分的位数 43 44 public: 45 Fraction() // 默认构造函数 46 { 47 intPart = 0; 48 decPart = 0; 49 cntDec = 0; 50 isCyc = false; 51 cycPart = 0; 52 cntCyc = 0; 53 } 54 55 Fraction(string str) 56 { 57 intPart = 0; 58 decPart = 0; 59 cntDec = 0; 60 isCyc = false; 61 cycPart = 0; 62 cntCyc = 0; 63 int i = 0, len = str.size(); 64 while (i < len && str[i] != ‘.‘) // 计算整数部分 65 { 66 intPart = intPart * 10 + str[i] - ‘0‘; 67 i++; 68 } 69 if (i < len) // 小数部分存在 70 { 71 i++; 72 while (i < len && str[i] != ‘(‘) // 计算循环体前小数部分 73 { 74 decPart = decPart * 10 + str[i] - ‘0‘; 75 i++; 76 cntDec++; 77 } 78 if (i < len) // 循环体存在 79 { 80 i++; 81 isCyc = true; 82 while (i < len && str[i] != ‘)‘) 83 { 84 cycPart = cycPart * 10 + str[i] - ‘0‘; 85 i++; 86 cntCyc++; 87 } 88 } 89 } 90 } 91 92 string toString() 93 { 94 string ret; 95 int numerator = 0, denominator = 0; 96 if (isCyc) 97 { 98 denominator = tenPow(cntDec) * (tenPow(cntCyc) - 1); 99 numerator = decPart * (tenPow(cntCyc) - 1) + cycPart; 100 } 101 else 102 { 103 denominator = tenPow(cntDec); 104 numerator = decPart; 105 } 106 int g = gcd(numerator, denominator); // 约分 107 numerator /= g; 108 denominator /= g; 109 numerator += denominator * intPart; 110 ret = intToString(numerator) + " / " + intToString(denominator); 111 return ret; 112 } 113 }; 114 115 int main(int argc, char *argv[]) 116 { 117 string str; 118 while (cin >> str) 119 { 120 Fraction fr(str); 121 cout << fr.toString() << endl; 122 } 123 return 0; 124 }
标签:
原文地址:http://www.cnblogs.com/xiaoxxmu/p/5493373.html