我正在编写一个函数,它接受一个参数'n',它将使用递归公式将十进制转换为二进制数。
这是我对非递归函数的看法,但我需要弄清楚如何递归地编写它。
def dec2bin(n):
bStr = ''
if n < 0:
return 'Must be a positive integer'
elif n == 0:
return '0'
else:
bStr += str(n%2)
return bStr
答案 0 :(得分:6)
考虑你的基本情况。将答案直接写入您的程序有什么意义? 0? 1?可能不仅仅是那个;你不希望一个巨大的elif
链上升到“好吧,如果它是314,我们就可以返回'100111010'
”。考虑一下你需要多少个数字来对答案进行硬编码,作为递归的一种基础,以及哪些数字你可以而且应该有算法处理。
考虑一下你的递归电话。如果你想生成n
的二进制表示,那么对dec2bin
的调用会得到大部分答案,那么你可以稍微修改一下结果并返回它?好吧,如果n
大于1
,n
的二进制表示形式是n//2
的二进制表示形式,另一个数字卡在末尾,就像小数表示的n
是n//10
的十进制表示,末尾有另一个数字。
答案 1 :(得分:5)
你的代码几乎没问题。您实际上不必维护bStr
。假设你知道n//2
的二进制表示,那么n
的二进制表示是n//2
和0
的二进制表示,如果n
可以被{{1}整除}或2
。
与1
= n
一样。 3
= n//2
。 1
所以dec2bin(n//2) = '01'
= dec2bin(n)
[因为'01'+'1'
3
不能被2
整除| '011'
你的代码应该是这个。
def dec2bin(n):
if n < 0:
return 'Must be a positive integer'
elif n == 0:
return '0'
else:
return dec2bin(n//2) + str(n%2)
就是这样。
答案 2 :(得分:1)
为了改善 rnbguy 的答案,我发现,当您的输入是除0
以外的任何数字时,它实际上会返回带有附加{{1}的二进制表示形式}。
要删除此问题,我想出的唯一解决方案是添加一个全局变量,该变量记住模数'0'
的先前值:
n%2
其原因是当您尝试prev = 0
def dec2bin(n):
global prev
if n < 0:
return 'Must be a positive integer'
elif n == 0:
if prev == 0:
return '0'
else:
prev = 0
return ''
else:
m = n%2
prev = m
return dec2bin(n//2) + str(m)
时输出为divmod(0, 2)
,因此我们知道输出必须是简单的(0, 0)
。但是,如果我们有一个大于0的数字,则递归函数将始终结束对'0'
和1//2
的除法,其结果将与1%2
相同。
要在输出末尾逃避另一个divmod(1, 2) == (0, 1)
,我们将'0'
的{{1}}保存在全局变量1
中,并在{{1 }},因为我们目前有1%2
。
之前:
prev
之后:
prev != 0
请注意,我们必须在n = 0
旁边添加>>> print dec2bin(22)
010110
>>> print dec2bin(0)
0
,否则自从上次执行的代码将>>> print dec2bin(22)
10110
>>> print dec2bin(0)
0
设置为prev = 0
以来,return ''
将不会输出任何内容。 / p>
答案 3 :(得分:0)
这是@Stickysli对@rnbguy解决方案的“改进”。解决的问题是不必要的前导0,但以使其自身不会产生空结果的方式消除它。拟议的“改进”非常复杂(超过原始代码行数的两倍),并且依赖于写入全局变量!
我相信,通过使用测试来查看是否要对数字1进行递归,我们可以用比原始代码更少的代码行来解决该问题,因为这就是问题的根源:
def dec2bin(n):
if n < 0:
raise ValueError("Must be a positive integer")
digit = str(n % 2)
return dec2bin(n // 2) + digit if n > 1 else digit
之后:
>>> dec2bin(22)
'10110'
>>> dec2bin(0)
'0'
>>>