leetcode
leetcode 2801 ~ 2850
二进制数转字符串

二进制数转字符串

难度:

标签:

题目描述

Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary representation. If the number cannot be represented accurately in binary with at most 32 characters, print "ERROR".

Example1:

 Input: 0.625
 Output: "0.101"

Example2:

 Input: 0.1
 Output: "ERROR"
 Note: 0.1 cannot be represented accurately in binary.

Note:

  • This two charaters "0." should be counted into 32 characters.
  • The number of decimal places for num is at most 6 digits

代码结果

运行时间: 24 ms, 内存: 16.0 MB


/*
 * 思路:
 * 使用Java Stream API进行二进制表示转换。
 * 与传统方法类似,反复乘以2并检查整数部分。
 * 使用StringBuilder累加二进制字符,超过32位则返回"ERROR"。
 */
import java.util.stream.Stream;
public class BinaryRepresentationStream {
    public String printBinary(double num) {
        if (num <= 0 || num >= 1) return "ERROR";
        StringBuilder binary = new StringBuilder("0.");
        Stream.iterate(num, n -> n * 2)
                .limit(32)
                .peek(n -> {
                    if (binary.length() < 32) {
                        if (n >= 1) {
                            binary.append(1);
                            n -= 1;
                        } else {
                            binary.append(0);
                        }
                    }
                })
                .allMatch(n -> binary.length() < 32 && n > 0);
        return binary.length() < 32 ? binary.toString() : "ERROR";
    }

    public static void main(String[] args) {
        BinaryRepresentationStream brs = new BinaryRepresentationStream();
        System.out.println(brs.printBinary(0.625)); // 输出: 0.101
        System.out.println(brs.printBinary(0.1));   // 输出: ERROR
    }
}

解释

方法:

这个题解的思路首先是将输入的浮点数分为整数部分和小数部分。整数部分直接使用Python内置的bin函数转换成二进制,然后将小数部分乘以10的6次方并取整,得到一个较大的整数。这个整数被用于通过一系列的减法操作来确定它的二进制位。题解中设置了一个固定的模数列表,这些模数分别对应二进制小数位的1/2, 1/4, 1/8等的值。算法迭代地检查每个模数能否被当前的数整除,并相应地更新数值。如果在处理完所有模数后,数值不为零,算法返回'ERROR'表示无法精确表示。最后,算法检查尾部的零并去除,生成最终的二进制表示。

时间复杂度:

O(1)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么选择将小数部分乘以10的6次方而不是其他数值?这样的选择对结果的精度有何影响?
选择将小数部分乘以10的6次方是为了尽可能地提高转换过程中的精确度,同时也保证处理过程在计算机中的实用性。10的6次方(即1000000)能够确保大部分需要精确到六位小数的数都可以在不产生过多溢出的情况下被处理。这个数值足够大,可以在不失去太多精度的情况下将小数部分转换为一个较大的整数,便于后续的二进制转换。如果选择更小的数,比如10的3次方或更小,可能无法捕捉到足够的小数精度;而选择更大的数虽然可以增加精度,但可能会导致在某些环境下处理大数时的性能问题。
🦆
在使用固定模数列表处理二进制小数部分时,你是如何确定这些特定的模数值(如500000, 250000等)的?这些值是否与特定的二进制位精度直接相关?
这些模数值是基于二进制小数位的权重确定的。在二进制系统中,每一位小数对应的权重是2的递减幂次。例如,第一位小数位对应1/2,第二位对应1/4,第三位对应1/8,以此类推。将小数乘以10的6次方后,这些权重可以转换为整数模数。500000代表1/2,250000代表1/4,125000代表1/8等。这样的设计确保了每个小数位对应的二进制位可以通过整除和取余操作来确定,是与特定的二进制位精度直接相关的。
🦆
题解中提到如果处理完所有模数后数值不为零就返回'ERROR',这种情况下是如何判断一个数字无法被精确地用32位二进制表示的?具体的逻辑是什么?
当处理完所有模数后,如果数值不为零,这意味着小数部分不能被完全表示为二进制小数的有限序列。在二进制表示中,只能精确表示那些小数部分为2的负整数幂次之和的数。如果在限定的模数处理后仍有剩余的数值,这表明原始数无法通过简单的2的幂次分解来完全表示。由于题目限制了32位的输出长度,包括'0.'在内,如果不能在这个长度内完全表示小数部分,就必须返回'ERROR'。这种判断逻辑保证了二进制表示的精确性和实用性。

相关问题