添加二进制数而不转换为十进制或使用内置函数

时间:2016-08-09 00:50:15

标签: python

我添加了两个以字符串形式输入的二进制数,并使用此method将它们的和以二进制形式输出。

有关让我的代码工作的任何想法吗?

def add(a,b):
    a = list(a)
    b = list(b)
    equalize(a,b)
    sum_check(a,b,ctr)
    out = " ".join(str(x) for x in sum_check(a,b,ctr))
    out.replace(" ","")
    print(out)

def equalize(a,b):
    if len(a) > len(b):
        for i in range(0, len(a)-len(b)):
            b.insert(0,'0')
    elif len(a) < len(b):
        for i in range(0, len(b)-len(a)):
            a.insert(0,'0')

def sum_check(a,b):

    out = []
    ctr = 0

    def sum(a, b):

        if ctr > 0:
            if a[-1] + b[-1] == 2:
                out.append('1')
            elif a[-1] + b[-1] == 0:
                out.append('1')
                ctr -= 1
            else:  # a[-1] + b[-1] = 1
                out.append('0')
                ctr -= 1
        else:  # ctr = 0
            if a[-1] + b[-1] == 2:
                out.append('1')
                ctr += 1
            elif a[-1] + b[-1] == 0:
                out.append('0')
            else:  # a[-1] + b[-1] = 1
                out.append('1')

    for i in range(len(a)):
        if i == 0:
            sum(a,b)
        else:
            new_a = a[:-1]
            new_b = b[:-1]
            sum(new_a, new_b)

    return out

1 个答案:

答案 0 :(得分:0)

你的算法并不是很简单(我会完全重写它;我也至少会给函数和变量更明确的名称,以便以后更快地理解算法,就像ctr无论如何应该明确地与携带有关等)。

然而,在这里,它是,纠正和工作。我在更改内容的地方插入了一些注释(算法中的错误或python编程错误)。

我已将def sum(...)放在sum_check之外,这样更清晰。

虽然您应该知道sumpython builtin,但您应该找到另一个名称,以避免丢失命名空间中的内置内容(但我猜您的算法仅用于培训目的,因为您可以通过直接对二进制数进行操作来替换所有这些:

$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = int('10110', 2)
>>> b = int('1011100', 2)
>>> bin(a + b)
'0b1110010'
>>> 

)。

另外,我留下了一些调试print语句,以帮助查看会发生什么。再加上一个检查所有案例的例子。

最后注意:它首先崩溃,因为您在定义它之前使用了ctr。这是第一件要纠正的事情。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


def equalize(a, b):
    if len(a) > len(b):
        for i in range(0, len(a) - len(b)):
            b.insert(0, 0)
    elif len(a) < len(b):
        for i in range(0, len(b) - len(a)):
            a.insert(0, 0)
    return a, b


def sum(a, b, ctr):
    out = ''
    print('\n'.join(['-------', 'Working on:',  str(a), str(b)]))

    if ctr > 0:
        if a[-1] + b[-1] == 2:
            out = '1'
            print('Case 1')
        elif a[-1] + b[-1] == 0:
            out = '1'
            ctr -= 1
            print('Case 2')
        else:  # a[-1] + b[-1] = 1
            out = '0'
            print('Case 3')
            # ctr -= 1 (wrong)
    else:  # ctr = 0
        if a[-1] + b[-1] == 2:
            out = '0'  # '1' was wrong
            ctr += 1
            print('Case 4')
        elif a[-1] + b[-1] == 0:
            out = '0'
            print('Case 5')
        else:  # a[-1] + b[-1] = 1
            out = '1'
            print('Case 6')
    print('Sum will return: ' + str(out)
          + ' and carry: ' + str(ctr) + '\n-------')
    return out, ctr


def sum_check(a, b):
    ctr = 0
    out = []
    n = len(a)
    for i in range(n):
        if i != 0:
            # You were always giving the same a and b to feed sum().
            # In order to change them, as it's not advised to iterate over a
            # changing list (maybe not even possible), I stored the desired
            # length in a number n. Then, I assign new values to a and b.
            a = a[:-1]
            b = b[:-1]
        new_out, ctr = sum(a, b, ctr)
        out.append(new_out)
        print('Current out: ' + str(out) + ' and carry: ' + str(ctr))
    return out


def add(a, b):
    a = [int(x) for x in a]
    b = [int(x) for x in b]

    # You need to return the new contents of a and b, otherwise you'll keep
    # them as they were before the call to equalize()
    a, b = equalize(a, b)

    print('\n'.join(['Equalized: ', str(a), str(b)]))
    # On next line, [::-1] reverses the result (your algorithm returns a
    # result to be read from right to left)
    print('Result: ' + ''.join(sum_check(a, b)[::-1]))


add('10110', '1011100')

输出:

Equalized: 
[0, 0, 1, 0, 1, 1, 0]
[1, 0, 1, 1, 1, 0, 0]
-------
Working on:
[0, 0, 1, 0, 1, 1, 0]
[1, 0, 1, 1, 1, 0, 0]
Case 5
Sum will return: 0 and carry: 0
-------
Current out: ['0'] and carry: 0
-------
Working on:
[0, 0, 1, 0, 1, 1]
[1, 0, 1, 1, 1, 0]
Case 6
Sum will return: 1 and carry: 0
-------
Current out: ['0', '1'] and carry: 0
-------
Working on:
[0, 0, 1, 0, 1]
[1, 0, 1, 1, 1]
Case 4
Sum will return: 0 and carry: 1
-------
Current out: ['0', '1', '0'] and carry: 1
-------
Working on:
[0, 0, 1, 0]
[1, 0, 1, 1]
Case 3
Sum will return: 0 and carry: 1
-------
Current out: ['0', '1', '0', '0'] and carry: 1
-------
Working on:
[0, 0, 1]
[1, 0, 1]
Case 1
Sum will return: 1 and carry: 1
-------
Current out: ['0', '1', '0', '0', '1'] and carry: 1
-------
Working on:
[0, 0]
[1, 0]
Case 2
Sum will return: 1 and carry: 0
-------
Current out: ['0', '1', '0', '0', '1', '1'] and carry: 0
-------
Working on:
[0]
[1]
Case 6
Sum will return: 1 and carry: 0
-------
Current out: ['0', '1', '0', '0', '1', '1', '1'] and carry: 0
Result: 1110010