LC-166 分数到小数

主要目标:

输入2个整数,如果为循环小数,小数部分将循环部分用“()”显示。

 

思路:

很麻烦,这道题还涉及到int整形的边界,为了避免处理这种情况,我们使用c++11的特性,int64_t来处理大数情况。

主要思路,首先将分子为零的直接返回“0”,然后记录答案正负符号,将分子和分母分别取绝对值,然后计算整数部分并记录下。

对于小数部分,我们把第一次除法后的余数记录下来,用长除法来计算接下来的小数部分,并用一个map结构来记录每个余数的出现位置,当重复出现余数,证明小数部分产生循环,估对该余数第一次出现的小数位置,插入‘(’符号

计算结束后,加上‘)’符号。

 

代码:

 1 class Solution {
 2 public:
 3     string fractionToDecimal(int64_t numerator, int64_t denominator) {
 4         // 分子为0,则结果为0
 5         if (numerator == 0) return "0";
 6         string ans;
 7         // 记录符号
 8         if (numerator < 0 ^ denominator < 0)
 9             ans += '-';
10         // 将分子分母变为整数
11         numerator = abs(numerator);
12         denominator = abs(denominator);
13         // 计算整数部分
14         ans += to_string(numerator / denominator);
15         // 记录余数
16         int64_t remainder = numerator % denominator;
17         // 检查是否整除
18         if (remainder == 0)
19             return ans;
20         // 计算小数部分
21         ans += '.';
22         map<int64_t, int> remainders;
23         int pos = ans.length(); // pos用于记录当前添加的小数在答案中的位置
24         int add_pos = 0;
25         bool flag = false; // 用于记录是否出现循环
26         while (remainder != 0 && !flag) {
27             // 若重复出现余数,则证明出现循环
28             if (remainders.find(remainder) != remainders.end()) {
29                 add_pos = remainders[remainder];
30                 flag = true;
31                 continue;
32             }
33             // 记录余数出现的位置,顺便递增pos
34             remainders[remainder] = pos++;
35             ans += to_string(10 * remainder / denominator);
36             remainder = (10 * remainder) % denominator;
37         }
38         if (flag) {
39             ans.insert(ans.begin() + add_pos, '(');
40             ans += ')';
41         }
42         return ans;
43     }
44 };

 

posted @ 2018-09-09 14:41  leo_lee  阅读(732)  评论(0编辑  收藏  举报