Python 无乘法运算符乘法的更好解决方案

Python 无乘法运算符乘法的更好解决方案,python,recursion,bit-manipulation,Python,Recursion,Bit Manipulation,我从“破解编码面试”中提出了以下问题的解决方案。我认为从他们的解决方案中看到的情况来看,它更快、更优雅,但不确定它是否适用于所有情况。有人能告诉我我是否错过了一些边缘案例吗 CTCI的原始问题是(关于递归和动态规划的问题8.5): 编写一个递归函数,将两个正整数相乘,而不使用*运算符。可以使用加法、减法和位移位,但应尽量减少这些操作的次数 我的解决办法是: def foo(a, b, mult = 0): if a == 0 or b == 0: return 0

我从“破解编码面试”中提出了以下问题的解决方案。我认为从他们的解决方案中看到的情况来看,它更快、更优雅,但不确定它是否适用于所有情况。有人能告诉我我是否错过了一些边缘案例吗

CTCI的原始问题是(关于递归和动态规划的问题8.5):

编写一个递归函数,将两个正整数相乘,而不使用*运算符。可以使用加法、减法和位移位,但应尽量减少这些操作的次数

我的解决办法是:

def foo(a, b, mult = 0):
    if a == 0 or b == 0:
        return 0

    if (a & 1) == 1:
        return (b << mult) + foo(a >> 1, b, mult + 1)

    return foo(a >> 1, b, mult + 1)
def foo(a,b,mult=0):
如果a==0或b==0:
返回0
如果(a&1)==1:
返回(b>1,b,mult+1)
返回foo(a>>1,b,mult+1)

有人能告诉我是否遗漏了什么吗?

使用乘法的基础,即5x3是“5加3倍”(5+5+5)或“3加5倍”(3+3+3+3+3)

此解决方案有1个加法和1个减法:

def乘法(a,b):
如果b==1:
归还
返回a+乘(a,b-1)#加减
乘(5,3)
# 15
乘(7,4)
# 28
乘(2000,1000)
# 2000000
您可以通过将
b
指定为两个数字中的较小者来减少递归发生的次数-将其放在函数的开头:

a, b = max(a, b), min(a, b)
# or
a, b = (a, b) if a >= b else (b, a)
将这些因素结合起来,形成几乎一条直线:

def乘法(a,b):
a、 如果a>=b,则b=(a,b)否则(b,a)
如果b==1,则返回a,否则a+乘法(a,b-1)
乘(2,1,000)
# 2000000

您可以使用位移位来执行基数2中的乘法:

def multiply(A,B):
    result = 0
    while A:
        if A&1: result = result + B # Add shifted B if last bit of A is 1
        A >>= 1 # next bit of A
        B <<= 1 # shift B to next bit position
    return result

print(multiply(7,13)) # 91
因此,编写递归版本相对容易:

def multiply(A,B):
    if A == 0: return 0
    result = multiply(A>>1,B)<<1  # get the higher bit product
    if A&1: result = result + B   # add the last bit multiplier (B)
    return result
def乘法(A,B):
如果A==0:返回0

result=multiply(A>>1,B)位移位可用于将乘法乘以2。用二进制写下乘法,看看这有什么帮助

考虑一下
5*7
,二进制格式为
101*111
。应用分布性,可以得到:

101 * 111 = 111 * (100 + 001)
          = 111 * 100 + 111 * 001
          = 7 * 4 + 7 * 1
          = 7 * 2² + 7*2⁰
通常,给定一个乘法
X*Y
,您可以将
X
划分为
n
2次幂的和,并将乘法写成
2^k*Y
形式的项和。出现在you系列中的术语对应于那些索引,在这些索引中,you的二进制表示形式中有一个
1

因此,递归算法是从右到左查看一个操作数的二进制数字,并对看到
1
的项求和

def mult(a, b):
    if a & 1:
        return b + mult(a >> 1, b << 1)
    if a:
        return mult(a >> 1, b << 1)
    else:
        return 0

print(mult(9, 7))  # 63
def mult(a,b):
如果a&1:

返回b+mult(a>>1,b>1,b我不会对建议的解决方案给出太多。该代码的作者甚至将第一个简单的实现搞错了:DMy其他答案是非递归的(因此我删除了它),但使用重复加法的简单一行:
def multiply(a,b):返回和(a表示范围内的uu(b))
def mult(a, b):
    if a & 1:
        return b + mult(a >> 1, b << 1)
    if a:
        return mult(a >> 1, b << 1)
    else:
        return 0

print(mult(9, 7))  # 63