Karotsuba乘法无法找到错误

2024-09-27 04:22:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做斯坦福大学的算法MOOC,却被卡拉通巴乘法算法编程作业困住了。
Karatsuba乘法是一种简单的两个整数的乘法算法,其速度比通常的乘法快

限制

  • 我限制自己只使用单位数乘法和填充数(在末尾加零,即乘以10的幂),因此有3种基本情况
  • 我还决定将数字转换成字符串,并取几个数字,而不是将其除以10的幂,但我尝试了另一种方法,它没有帮助
  • 我还决定推广该算法,即不要假设number1和number2具有相似的长度,因此我同时使用n1和n2(参见代码)
  • 由于上述原因,我也决定不使用高斯技巧

我知道,这些限制可能看起来毫无意义,但我将其用作编程练习,而不是一些实际的解决方案,因此我主要感兴趣的是发现我的错误,而不是找到一些“更简单的解决方案”

这是我的密码:

    def karatsuba(number1, number2):
        n1 = len(str(number1)) # number of digits in the first number
        n2 = len(str(number2)) # number of digits in the second number

        if n1 == 1 and n2 == 1: # base case number 1 - both numbers are single-digit
            kara = number1*number2
            return kara

        elif n1 == 1: # base case number 2 - only one number is single-digit
            c = int(str(number2)[:(n2//2)])
            d = int(str(number2)[(n2//2):])
            kara = 10**((n2+1)//2)*c*number2 + d*number2
            return kara

        elif n2 == 1: # base case number 3 - only one number is single digit
            a = int(str(number1)[:(n1//2)])
            b = int(str(number1)[(n1//2):])
            kara = 10**((n2+1)//2)*a*number2 + b*number2
            return kara

        elif n1 != 1 and n2 != 1: # loop
            a = int(str(number1)[:(n1 // 2)])
            b = int(str(number1)[(n1 // 2):])
            c = int(str(number2)[:(n2 // 2)])
            d = int(str(number2)[(n2 // 2):])
            z1 = karatsuba(a, c)
            z2 = karatsuba(a, d)
            z3 = karatsuba(b, c)
            z4 = karatsuba(b, d)
            kara = 10**((n1+1)//2+(n2+1)//2)*z1 + 10**((n1+1)//2)*z2 + 10**((n2+1)//2)*z3 + z4
            return kara

Tags: 算法numberbasereturnintcasesingle乘法
2条回答

这不是卡拉祖巴算法。Karatzuba的要点是只进行3次递归调用;你做了四个。在您的符号中,递归调用应该是

karatzuba(a, c)
karatzuba(b, d)
karatzuba(a + b, c + d)

除此之外,基本情况2还有一个问题:number1根本不参与其中

如果你还没有改正,这些都是需要改正的错误

kara = 10**((n2+1)//2)*c*number1 + d*number1 #in base case 2 
kara = 10**((n1+1)//2)*a*number2 + b*number2 #in base case 3. your code has n2+1

传统的Karatsuba有3个递归。但我明白你为什么要进行4次递归。但不能说哪个更快

上面注释中给出的示例的工作代码

def karatsuba(number1, number2):
    n1 = len(str(number1)) # number of digits in the first number
    n2 = len(str(number2)) # number of digits in the second number

    if n1 == 1 and n2 == 1: # base case number 1 - both numbers are single-digit
        kara = number1*number2
        return kara

    elif n1 == 1: # base case number 2 - only one number is single-digit
        c = int(str(number2)[:(n2//2)])
        d = int(str(number2)[(n2//2):])
        kara = 10**((n2+1)//2)*c*number1 + d*number1 #a mistake here
        return kara

    elif n2 == 1: # base case number 3 - only one number is single digit
        a = int(str(number1)[:(n1//2)])
        b = int(str(number1)[(n1//2):])
        kara = 10**((n1+1)//2)*a*number2 + b*number2 #a mistake here
        return kara

    elif n1 != 1 and n2 != 1: # loop
        a = int(str(number1)[:(n1 // 2)])
        b = int(str(number1)[(n1 // 2):])
        c = int(str(number2)[:(n2 // 2)])
        d = int(str(number2)[(n2 // 2):])
        z1 = karatsuba(a, c) 
        z2 = karatsuba(a, d) 
        z3 = karatsuba(b, c)
        z4 = karatsuba(b, d) 
        kara = 10**((n1+1)//2+(n2+1)//2)*z1 + 10**((n1+1)//2)*z2 + 10**((n2+1)//2)*z3 + z4
        return kara
num1 = 3141592653589793238462643383279502884197169399375105820974944592
num2 = 2718281828459045235360287471352662497757247093699959574966967627
k_res = karatsuba(num1,num2)
ac_res = num1*num2
print(k_res)
print(ac_res)
assert k_res==ac_res

相关问题 更多 >

    热门问题