题目描述#

哎呀,咱来翻译下题面~给你两个用字符串表示的二进制数 ab,返回它们相加之后、同样用二进制字符串表示的结果。

输入只含 '0''1',而且除了 "0" 本身之外,开头不会有多余的前导零。

思路#

咱第一眼看,这题别被"二进制"三个字唬住——它本质就是小学的竖式加法,只不过逢二进一而已。

既然是竖式,那就得从**最低位(字符串末尾)往最高位(开头)**逐位相加。咱用两个指针 ij 分别指向 ab 的末尾,再拿一个 carry 记进位。

每一轮咱把三样东西加起来:进位 carry、当前 a[i]、当前 b[j]。注意字符 '0'/'1' 要先减掉 '0' 才变成真正的数字 0/1。加完得到 sum 之后:

  • 当前位的结果就是 sum % 2(逢二进一,所以对 2 取余);
  • 新的进位就是 sum / 2(整除 2,要么是 0 要么是 1)。

循环什么时候停?只要 a 还没走完、b 还没走完、或者进位还没处理干净,就得继续。那个 carry > 0 的条件特别关键——比如 "1" + "1" 最后会多出一个最高位的 1,要是漏了它结果就少一位啦。

因为咱是从低位往高位算的,而结果字符串要从高位往低位读,所以每算出一位就把它拼到答案最前面ans = 新位 + ans)。本姑娘提醒一句:这样拼天然就把顺序摆正了,不用最后再反转~

照片当然不是现实,但只要一位一位拍够了,拼起来就是完整的那张图——加法也是,一位一位进上去,答案自然成形。

知识边界#

  • 字符与数字的转换a[i] - '0' 把字符 '1' 转成整数 1,反过来 byte(x) + '0' 把数字转回字符。漏减 '0' 会直接拿到 ASCII 码('1' 是 49),结果全错——这点容易踩坑哦。
  • 逢二进一sum % 2 取当前位,sum / 2 取进位。换成十进制加法就是 % 10/ 10,一套模板通用。
  • 进位的收尾:循环条件里的 carry > 0 不能省,否则最高位的进位会丢失(如 "11" + "1")。
  • 字符串前插ans = string(...) + ans 把新位拼到最前,省去最后反转。不过 Go 里字符串是不可变的,这种前插每次都会重新分配,数据量大时换 []byte 倒序填充 + 反转会更高效——本题数据小,这么写够清楚。
  • string(byte) 的坑:这里 byte(sum%2)+'0' 已经是一个合法的 ASCII 字符字节,再用 string(...) 转成单字符字符串是 OK 的;别误用成 string(数字)(那会按 Unicode 码点转,结果不对)。

代码#

下面这版咱一行没动,逻辑就是上面那套竖式:

func addBinary(a string, b string) string {
    i := len(a) - 1
    j := len(b) - 1
    carry := 0
    ans := ""
    for i >= 0 || j >= 0 || carry > 0 {
        sum := carry
        if i >= 0 {
            sum += int(a[i] - '0')
            i--
        }
        if j >= 0 {
            sum += int(b[j] - '0')
            j--
        }
        // 当前位
        ans = string(byte(sum%2)+'0') + ans
        // 进位
        carry = sum / 2
    }
    return ans
}
本站总访问量  ·  访客数
你的IP 获取中…