【问题标题】:How to recursively program a multiplication algorithms如何递归地编程乘法算法
【发布时间】:2020-05-31 20:15:14
【问题描述】:

我开始了一门新的算法课程。教授正在尝试用其他规则创建一个乘法算法。

例如,他将我们试图相乘的数字分成两组。 x = 3452 然后是a = 34b = 52(同样适用于y)。

据他说,基本操作是:

如果给你两个数字,每个数字只有一个数字。然后 您只需将它们乘以一个基本操作并返回结果。

如果 acadbcbd 是非常简单的操作,您将如何递归计算它们?

【问题讨论】:

    标签: algorithm recursion integer karatsuba


    【解决方案1】:

    以下是您将如何为 karatsuba 编写代码(在 python 中)(假设 x 和 y 始终具有相同的偶数位数):

    def numDigits(x):
      """
      Returns the number of digits in x
      """
      if x == 0:
        return 1
    
      digits = 0
      while x >= 1:
        x = int(x / 10)
        digits+=1
      return digits
    
    def multiply(x, y):
      x_digits = numDigits(x)
      y_digits = numDigits(y)
    
      if x_digits != y_digits:
        return -1                    # not valid
    
      n = x_digits
    
      if n == 1:                     # checks if x (and y) are only 1 digit
        return x*y                   # single digit multiplication
    
      half_n = int(n / 2)
    
      a = int(x / (10**half_n))
      b = x - (a*(10**half_n))
      c = int(y / (10**half_n))
      d = y - (c*(10**half_n))
    
      ac = multiply(a, c)
      ad = multiply(a, d)
      bc = multiply(b, c)
      bd = multiply(b, d)
    
      return (10**n)*ac + (10**half_n)*(ad + bc) + bd
    
    
    
    assert multiply(1, 2) == 2
    assert multiply(10, 20) == 200
    assert multiply(15, 21) == 315
    assert multiply(1710, 2450) == 4189500
    print("all pass!")
    

    您可以修改代码以允许 x 和 y 具有奇数位数并具有不同的长度,但需要做更多工作。

    【讨论】:

    • 所以要编码*,你需要/,**,这听起来不对……是的,它可能会导致正确的答案,但你正在使用更高的运算来计算更低的运算。这很慢,如果你想实现 ** 后者怎么办?如果是(通常是这种情况),它会使用*吗?它不可能使用你当前的实现,因为它会立即导致堆栈溢出。 Karatsuba 只能通过较低的操作轻松完成...
    • 递归部分不完整,但这是 Python 的问题,因为您不处理数据类型……在大多数语言中,您需要有一种机制来处理参数和返回值的位宽变化。
    • 乘以和除以 10 的幂可以使用左移/右移来完成。这需要 CPU O(n) 时间。
    • 位移是 2 除法/乘法的幂,对于 10 的幂,它是位移和加法的组合。但是,对于 bignums,如果内部表示正确完成,那么它的这种操作只是数据的纯副本(例如在字符串中插入或删除字符),而不是昂贵的 log/exp pow 方法,这通常会破坏 Karatsuba 在大多数菜鸟中对更大数字的功能实现...
    • @Spektre 那么您对上面的代码有何改进建议?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    相关资源
    最近更新 更多