二进制求和

64 阅读1分钟

思路

转数值,再相加,但是貌似更麻烦

直接定义一个字符相加的函数,本来想用传统的末尾相加的思路,发现写起来很麻烦

伪代码

func addBinary(a string, b string) string {
	strA, strB := []rune(a), []rune(b)

	lenA, lenB := len(strA), len(strB)
	minLen := lenA
	if minLen > lenB {
		minLen = lenB
	}

	head := '0'
	for i := 0; i < minLen; i++ {
		//得到一个进位head,一个余位rest
		addThree(strA[lenA-1-i], strB[lenB-1-i], head)
		//用一个新切片,余位存上,继续下个循环...
		//注意,加到开头还有进位的情况,可能超出原切片长度。。。
	}
	//返回新切片
}

func addThree(a, b, c rune) (rune, rune) {
	//三数相加,逻辑省略...
	return '0', '0'
}

func add(a, b rune) (rune, rune) {
	if a == '1' && b == '1' {
		return '1', '0'
	} else if a == '0' && b == '0' {
		return '0', '0'
	} else {
		return '0', '1'
	}
}

优化

  • 不用判断长度谁大谁小
  • 不用想着先转换位某种表示,在转换为二进制字符串。直接定义一个二进制结果字符串,拼接新值
  • 和/2 代表进位
func addBinary(a string, b string) string {
    i, j := len(a)-1, len(b)-1
    carry := 0
    result := ""

    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--
        }
        carry = sum / 2
        result = string(sum%2+'0') + result
    }

    return result
}