Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一个计算达到0步数的函数_Python_Zero - Fatal编程技术网

Python 一个计算达到0步数的函数

Python 一个计算达到0步数的函数,python,zero,Python,Zero,我需要写一个函数来计算达到零的总步数。规则是 除以2的数 然后减去1 例如,如果我有14号 14/2=7 7-1=6 6/2=3 3-1=2 2/2=1 1-1=0 总共有6个步骤 请注意,输入x是一个二进制字符串: def test(x): a = int(x,2) steps = 0 while a != 0: if a % 2 == 0: a = a // 2 else: a

我需要写一个函数来计算达到零的总步数。规则是

  • 除以2的数
  • 然后减去1
例如,如果我有14号

  • 14/2=7
  • 7-1=6
  • 6/2=3
  • 3-1=2
  • 2/2=1
  • 1-1=0
总共有6个步骤

请注意,输入x是一个二进制字符串:

def test(x):
    a = int(x,2)
    steps = 0
    while a != 0:
        if a % 2 == 0:
            a = a // 2  
        else:
            a = a - 1
        steps += 1
    return steps

我需要知道的是,有没有办法写出一个快速的函数?

对于奇数,你的算法是不正确的。只有当数字为偶数时才进行除法,这不是您所描述的“步骤”

你想要

def测试(x,2):
x_int=int(x)
步数=0

虽然x_int也可以使用递归方法:

def stepsToZero(N):
    return N if N < 2 else 2 + stepsToZero(N//2-1)
def步进至零(N):
如果N<2,则返回N,否则2+步进归零(N//2-1)
这将使您的结果高达N=2**993(这是一个相当大的数字),并具有一个非常简洁(而且更优雅)的函数

运行得更快的是从数学上解决这个问题

例如:

import math
def steps2Zero(N):
    if N < 2: return N
    d = int(math.log(N+2,2))-1
    s = int(N >= 3*2**d-2)
    return 2*d+s
导入数学
def步骤20(N):
如果N<2:返回N
d=int(数学日志(N+2,2))-1
s=int(N>=3*2**d-2)
返回2*d+s

注意,对于N=2^900,数学解比递归快一百倍。另一方面,递归函数在一秒钟内响应良好,可读性更高。因此,根据使用方法和大小数字,性能考虑可能是毫无意义的,前提是您的代码是正确的,并且规则是:

  • 测试(0)=0
  • 如果n为偶数,则测试(n)=1+测试(n/2)
    1+测试(n− 1) 否则
需要注意的重要事项是:

  • 偶数以二进制0结尾
  • 除以2将从末尾删除0(除此之外没有其他内容)
  • 奇数以二进制1结尾
  • 减去1将最后一个1变成0(除此之外没有其他值)
因此,除第一位外,每1位增加2步,每有效0位增加1步。这意味着对于以
1
开头的输入,您可以编写:

def test(x):
    return x.count('1') + len(x) - 1

现在你只需要对前导零点进行解释,或者只需要特定的情况,即“代码>0”<代码>,如果前导零点是不可能的。

如果你的代码工作,但是杂乱或太慢,考虑在CoDeEvIEW.StAcExchange。但您的代码建议您根据数字是否为偶数来选择一个。这个例子并没有消除歧义。是哪一个?在测试中,我的输入x总是偶数…奇数也可以。@potentialwjy:这并不能回答问题。递归比循环慢,如果N太大,将引发异常。我的错!输入是一个二进制字符串。请查看我更新的postmy fault!输入是一个二进制字符串。请看我更新的帖子这不起作用……假设我有int(“0010010001”,2)Out[73]:145……测试(“0010010001”)Out[68]:10@potentialwjy:它有前导零,因此您需要对此进行说明。减法
x.find('1')
,除非字符串中没有1。@可能wjy您应该更新您的问题以反映Ry实施的规则。它与您的描述不同,因为除2不一定是第一步,减法1的条件是中间结果为奇数。否则,结果将与公认的答案不同。例如:1001(9)应该只采取4个步骤,而不是5:9//2=4,4-1=3,3//2=1,1-1=0。如果10010(18)在第一次除以2后将产生9,那么以偶数开始将无法修复它。
import math
def steps2Zero(N):
    if N < 2: return N
    d = int(math.log(N+2,2))-1
    s = int(N >= 3*2**d-2)
    return 2*d+s
def test(x):
    return x.count('1') + len(x) - 1