题目:
Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
If the fractional part is repeating, enclose the repeating part in parentheses.
For example,
- Given numerator = 1, denominator = 2, return "0.5".
- Given numerator = 2, denominator = 1, return "2".
- Given numerator = 2, denominator = 3, return "0.(6)".
思路:
这个题,乍一看,似乎也没什么做头。但是accept rate只有12%,可见也不是那么好做。第一次提交了10次呵呵。第二遍做总算能一下过了。可是是凭记忆。
这个题对细节的问题考察很多,如果像我这种编程能力差得就一考一出错。总是忘这忘那。
主体思路很普通,模拟除法运算,用hashmap找到相同的余数出现的位置,意味着循环小数的起点终点。
但是细节需要考虑:
1)两者是否为零
2)符号是正是负
3)数据可能溢出,怎么解决
我在处理数据溢出的问题时,出了两个我一眼没看出的bug:
1. 建立的hashmap,key 的数据类型我无脑写成Integer,即HashMap<Integer, Integer>, 这样reminder存入时损失精度,永远找不到相同reminder了。无限循环。这就是基础比较差。
2. 我想到了要用long来存储numerator 和 denominator, 可我直接写成long num = Math.max(numerator); 错。
因为此时,numerator是个int,而如果输入为Interger.MIN_VALUE 即-2147483648, 这时Math.abs()的返回类型是int,没法取这个数的绝对值的。
java document:Note that if the argument is equal to the value of Integer.MIN_VALUE
, the most negative representable int
value, the result is that same value, which is negative.
所以这里该写成long num = numerator; num = Math.max(num);
代码,为了思路的简洁,可能代码并不简洁:
1 public String fractionToDecimal(int numerator, int denominator) { 2 if (numerator == 0) { 3 return "0"; 4 } 5 if (denominator == 0) { 6 return ""; 7 } 8 StringBuilder str = new StringBuilder(); 9 if (numerator < 0 ^ denominator < 0) { 10 str.append("-"); 11 } 12 long num = numerator; 13 num = Math.abs(num); 14 long den = denominator; 15 den = Math.abs(den); 16 long integer = num / den; 17 long reminder = num % den; 18 19 20 if (reminder == 0) { 21 str.append(integer); 22 return str.toString(); 23 } 24 25 HashMap<Long, Integer> map = new HashMap<Long, Integer>(); 26 int count = 0; 27 28 StringBuilder decimal = new StringBuilder(); 29 30 while (reminder != 0) { 31 if (!map.containsKey(reminder)) { 32 map.put(reminder, count); 33 decimal.append(reminder * 10 / den); 34 reminder = (reminder * 10 ) % den; 35 count++; 36 }else{ 37 int front = map.get(reminder); 38 decimal.insert(front, '('); 39 decimal.append(')'); 40 break; 41 } 42 } 43 44 str.append(integer).append('.').append(decimal); 45 return str.toString(); 46 47 }