这是对我们从小到大使用的乘法算法的一种替代方案,主要用于大位数数字的乘法。卡拉楚巴算法 用于大数字的快速乘法,它使用了一种著名的名为 分治法 的技术,由 Anatolii Alexeevitch Karatsuba 于 1960 年开发。在深入主题之前,让我们先看看它是在什么背景下以及为什么要被开发出来。
总共有 3 种数字乘法的方法:
- 三年级小学算法法(标准方法)
- 递归算法法
- 卡拉楚巴乘法法
为什么使用卡拉楚巴算法?
该算法旨在提供一个高度丰富的设计空间。其时间复杂度如下:
> O(n^log2(3)) 时间 (~ O(n^1.585))
>
> 其中 n 是相乘数字的位数。我们将通过两个大整数相乘来逐步讨论其内部工作原理。我们的目标是降低空间复杂度,为此,整数项将被分解,就像将 x 和 y 分解为一组数字一样,其背后的逻辑就是分治法。如果数字较小,则无需使用此算法,优先使用两个整数的标准乘法。
在本文中,为了便于理解,我们将该算法标准化为处理 4 位数字。实际上,我们可以对任意多组数字进行乘法运算。
该算法涉及的步骤:
- 如果 x < 10 或 y < 10,返回 x * y。
- 计算 halfLength = max(length(x), length(y)) / 2。
- 将 x 分割为 max1 = x / 10^halfLength 和 min1 = x % 10^halfLength。
- 将 y 分割为 max2 = y / 10^halfLength 和 min2 = y % 10^halfLength。
- 计算 ac = karatsubaMultiply(max1, max2)。
- 计算 bd = karatsubaMultiply(min1, min2)。
- 计算 ab_cd = karatsubaMultiply(max1 + min1, max2 + min2)。
- 计算结果 = (ac 10^(2 halfLength)) + ((ab_cd – ac – bd) * 10^halfLength) + bd。
现在让我们在得出结果之前,详细看看上述步骤的图解说明。
步骤图解:
****假设输入为:**** x = 1234, y = 5678
****给定:****
x = 1234
y = 5678
****步骤 1:**** 将 `x` 和 `y` 分成两部分:
a = 12, b = 34
c = 56, d = 78
****步骤 2:**** 计算乘积:
a * c = 12 * 56 = 672
b * d = 34 * 78 = 2652
****步骤 3****:计算 `(a + b)` 和 `(c + d)` 的和:
(a + b) = 12 + 34 = 46 // 你取的是 36
(c + d) = 56 + 78 = 134
****步骤 4****:计算 `(a + b)` 和 `(c + d)` 的乘积:
(a + b) * (c + d) = 46 * 134 = 6164
****步骤 5****:计算最终结果:
结果 = (a * c) * 10000 + (b * d) + (a + b) * (c + d)
结果 = 672 * 10000 + 2652 + 6164
结果 = 6720000 + 2652 + 6164
结果 = 6728816
****输出:**** 6728816
程序实现:
请注意,与其死记硬背该算法的公式,不如以这种方式来理解它,这样会更容易实现。
Java
CODEBLOCK_106f684f
Output
Product of 1234 and 5678 is 7006652