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 };