目录

string算法之二进制加法

最近寒风凛冽,估计不少同学都在刷算法题了,这里给大家介绍一个 python 实现的算法仓库,里面有很多常见算法的实现,有兴趣的同学可以先通过既有算法学习,掌握一些套路之后再由易到难把题刷起来。仓库地址:https://github.com/keon/algorithms

先给大家分享一个二进制加法的算法吧。

题目

输入:2 个二进制的字符串

输出:也以二进制的方式返回相加后的结果

比如

a = "11"
b = "1"
Return "100"

分析

这道题看完之后我基本上没有任何思路,丝毫没有一点点挣扎,直接看答案了。

实现

def add_binary(a, b):
    s = ""
    c, i, j = 0, len(a)-1, len(b)-1
    zero = ord('0')
    while (i >= 0 or j >= 0 or c == 1):
        if (i >= 0):
            c += ord(a[i]) - zero
            i -= 1
        if (j >= 0):
            c += ord(b[j]) - zero
            j -= 1
        s = chr(c % 2 + zero) + s
        c //= 2

    return s

看完以后发现实现思路非常的精妙。

首先确定’0’这个字符的 ascii 码,zero 的值就是整形的 48。

下面遍历两个字符串的每一位,从低位到高位,如果当前位存在的话,则取这一位的 ascii 码减去 zero,因为是二进制,所以当前位的值要么是 0 要么是 1,所以每次遍历相减后得到的结果要么是 0 要么是 1,这就等于是把当前位从字符转成了二进制。所以后面如果有类似的字符或字符串转成二进制的题,可以参考每一位减去 ascii 0 的实现方式。

取一个数 c,保存两个字符串当前位的和,所以 c 的取值一定是固定的

  • 无进位的情况
    • c = 1 + 1 = 2
    • c = 1 + 0 = 1
    • c = 0 + 1 = 1
    • c = 0 + 0 = 0
  • 有进位,c 就等于 1
    • c = 1 + 1 + 1 = 3
    • c = 1 + 0 + 1 = 2
    • c = 0 + 1 + 1 = 2
    • c = 1 + 0 + 0 = 1

好了,下面再用 c 去模 2,在 c = 2 或者是 0 的时候,就可以得到当前位的值是 0,c 是 1 或 3 的时候当前位就是 1,这里用取模的方式实现了二进制的加法,简单却深刻和优雅。

最后一步改变 c 的值,如果 c=2 的话,证明是有进位的,其他情况下没有进位,所以把 c 的值变成 c 除以 2 的商,当且仅当 c 为 2 的时候,c 会变成 1,其他情况下由于不能整除,c 又恢复成 0,优雅的用整除实现了进位。

分解

以 a = 11, b = 1 为例子,每次从 ab 里取 1 位,分别记作 x,y,输出的字符串为 s,因此我们有 4 个变量,x,y,c,s

  1. x = 1, y = 1, c = x + y = 2, s = “” + c % 2 = “” + “0” = “0”, c = c / 2 = 1,第一步之后 s 是”0”, c = 1
  2. x = 1, y = 0, c = x + y = 2, s = “0” + c % 2 = “0” + “0”, c = c / 2 = 1,这一步之后 s 是”00”, c = 1
  3. c = 1, s = “0” + c % 2 = “00” + “1”, s = “100”, c = c / 2 = 1 / 2 = 0, 不满足循环条件,退出,最终结果 100

总结

其实没啥好总结的,这道题看起来简单,但是不看答案真不知道该怎么下手。