[LintCode] Binary Representation

Problem

Given a (decimal - e.g. 3.72) number that is passed in as a string, return the binary representation that is passed in as a string. If the fractional part of the number can not be represented accurately in binary with at most 32 characters, return ERROR.java

Example

For n = "3.72", return "ERROR".app

For n = "3.5", return "11.1".ui

Note

這道位操做的題目,主要分爲整數部分和小數部分的轉換。細節上還要考慮正負號和整數位的越界狀況。首先,咱們對字符串n.split("\\.")把小數點先後的部分分離,存入String[] parts,整數部分爲parts[0],小數部分爲parts[1]。而後將parts[0]經過Integer.parstInt()轉化爲int first,而後將first的正負設置爲符號位boolean isNeg,創建StringBuilder sb
下面開始整數部分的轉換,首先考慮越界狀況:當first的值爲Integer.MIN_VALUE的時候,二進制表達爲32個1,放入sb便可。不然對first的絕對值進行運算。對first(的最低位)和整數1作與運算,結果存入sb,而後右移一位,進行上一位和整數1的與運算,如此直到first爲0,轉換完畢。
小數部分相對更麻煩一些。首先,只有parts[]有兩個元素且parts[1]不爲0時,sb加入小數點'.',而後建立double value,使用Double.parseDouble("0." + parts[1])將小數部分存入value,和整數部分的操做基本一致。
而後咱們要考慮兩個問題value是否是可以徹底轉換爲二進制,以及保證可以在小數點後32位的範圍內完成轉換?
因此,咱們針對這兩點,寫出返回ERROR的分支語句。首先在循環外部創建一個HashSet store,循環內會將出現過的value存入store。而後在while循環內判斷,若是有重複出現的value,或者sb中小數部分的長度超過32,就說明該小數沒法徹底轉換。
而後根據新的value大小進行十進制到二進制轉換運算(value * 2(value < 0.5)value * 2 - 1(value >= 0.5)),將結果加入sb。若是以前的正負號isNegtrue,就在sb左邊加上負號'-'
最後,返回sb.toString()code

Solution

import java.math.*;
public class Solution {
    public String binaryRepresentation(String n) {
        if (n == null || n.length() == 0) {
            return n;
        }
        String[] parts = n.split("\\.");
        StringBuilder sb = new StringBuilder();
        int first = Integer.parseInt(parts[0]);
        boolean isNeg = first < 0;
        if (first == Integer.MIN_VALUE) {
            for (int i = 0; i < 32; i++) {
                sb.append("1");
            }
        } else {
            first = Math.abs(first);
            while (first != 0) {
                sb.insert(0, first & 1);
                first >>= 1;
            }
        }
        if (sb.length() == 0) {
            sb.append("0");
        }
        //now nail the decimal part
        if (parts.length == 2 && Long.parseLong(parts[1]) != 0) {
            sb.append(".");
            double value = Double.parseDouble("0." + parts[1]);
            Set<Double> store = new HashSet<>();
            while (value > 0) {
                if (sb.substring(sb.indexOf(".")).length() + 1 > 32 || store.contains(value)) {
                    return "ERROR";
                }
                store.add(value);
                if (value >= 0.5) {
                    sb.append("1");
                    value = value * 2 - 1;
                } else {
                    sb.append("0");
                    value = value * 2;
                }
            }
        }
        if (isNeg == true) {
            sb.insert(0, "-");
        }
        return sb.toString();
    }
}
相關文章
相關標籤/搜索