【问题标题】:Converting an integer number into a binary number using recursion使用递归将整数转换为二进制数
【发布时间】:2015-05-01 22:53:57
【问题描述】:

我正在尝试编写一个使用递归将给定整数转换为二进制数的脚本。这是我写的代码:

def dec2bin(n):
    if n > 0:
        if n%2 == 0:
            li.append(0)
        else:
            li.append(1)
        return dec2bin(n/2)    
    else:
        aa = li[::-1]
        for e in aa:
            print e,    
n = int(raw_input())
li = []
dec2bin(n)

但是,此代码会继续运行,并且永远不会输出正确的答案。这段代码似乎有什么问题?

【问题讨论】:

  • n 这里不是一个十进制数,它是一个int,它没有固有基数(或者,如果你想拉伸它并说它有一个,固有基数是二进制)。
  • 所以更正确地说,这个函数不是将十进制转换为二进制,它只是在二进制中打印一个正整数。那就是它是否有效。
  • keeps on running and never outputs the correct answer 我认为您忘记输入raw_input() 的输入,它只是在等待您的输入。
  • @Marein:如果它可以被2整除,那意味着它的最后一位是0。
  • @Marein 我的代码使用了以下链接中提到的算法:interactivepython.org/courselib/static/pythonds/BasicDS/…

标签: python python-2.7 recursion


【解决方案1】:

类似于 Brad Budlong 的解决方案,但在递归的最低级别创建列表,而不是使用全局或第二个参数。 (这是 Python 3.3,所以 print 是一个函数;如果需要,可以针对 Python 2.7 进行调整。也可以使用 // 运算符而不是 /)

def dec2bin(n):
    if n == 0:
        return []
    else:
        r = dec2bin(n//2)
        r.append(n%2)
        return r

print(dec2bin(10))
print(dec2bin(42))

【讨论】:

  • 不错。这可能是 理智的解决方案。
【解决方案2】:

这是一个可以考虑的替代方案,因为您正在研究递归。如果您切换追加和递归调用的顺序,那么您不必在最后反转列表。这让递归将 MSB 推迟到 LSB 已经被处理之后。最后它做了同样的事情,但更简单。

def dec2bin(n):
    if n > 0:
        dec2bin(n/2)
        li.append(n%2)
        print n%2,

我还删除了代码中的 return 语句,因为您没有返回任何内容。这个函数只是修改了 li 并打印出来。

【讨论】:

  • @Blckknght 您应该尝试运行它,您会看到它将 MSB 打印到 LSB。请注意,递归调用发生在打印之前,因此最深的递归调用(MSB)首先打印
【解决方案3】:

它适用于我,就像它适用于 cmets 中的其他人一样。

但是,它使用全局变量来存储结果有点难看,并且会让您受到各种干扰,我永远不想在生产代码中看到这种情况。 prints 同上。

你可以这样编辑它:

def dec2bin(n, li=None):
    if li is None:
        li = list()
    if n == 0:
        return li[::-1]
    else:
        if n%2 == 0:
            li.append(0)
        else:
            li.append(1)
        return dec2bin(n/2, li)    


print dec2bin(1) # [1]
print dec2bin(3) # [1, 1]
print dec2bin(8) # [1, 0, 0, 0]
print dec2bin(10) # [1, 0, 1, 0]

请特别注意li = list() - 请参阅http://effbot.org/zone/default-values.htm

另请注意,通过将 li.append(0) 替换为 [0]+li 并对奇数情况执行相同操作,您可以在不进行反转的情况下执行此操作(以降低可读性为代价)。

【讨论】:

  • 我不确定li = [0] + li 的可读性是否会降低……但如果您认为是,为什么不li.insert(0, 0)? (当然,性能成本;您正在用线性时间反转换取二次时间重复移动列表……但在这个用例中,我怀疑这是否重要,如果它确实,无论如何你都想测试它;直到你得到巨大的数字,移动列表时令人难以置信的低常数乘数可能意味着这不是问题……)
  • 我不知道,append 对我来说似乎是最易读的,但我们 正在分裂。
猜你喜欢
  • 2014-07-14
  • 1970-01-01
  • 2013-09-23
  • 2017-07-11
  • 1970-01-01
  • 2018-08-28
  • 2015-06-14
  • 2012-03-20
  • 2012-04-19
相关资源
最近更新 更多