📜  实现唐叶乘法算法的Java程序

📅  最后修改于: 2022-05-13 01:55:27.372000             🧑  作者: Mango

实现唐叶乘法算法的Java程序

它是小学数字乘法算法的替代品。更大的数字。 Karatsuba 算法使用分而治之的快速乘法算法由 Anatolii Alexeevitch Karatsuba 于 1960 年开发。首先想到的是它是什么以及为什么设计它。尽管有 3 种方法可以将数字相乘:

  1. 三年级算法法(Standard-way)
  2. 递归算法方法
  3. 唐叶乘法

为什么是 Karatsuba 算法?

设计算法的目标是因为设计空间惊人地丰富。它的时间复杂度如下所示,因为时间复杂度非常重要,有时在面试问题中会被问到。

为了便于理解,算法被标准化为 4 位数字。一个人可以乘以作为集合的数字。

算法步骤:

  1. 计算起始集 (a*c)
  2. 开始集之后的计算集可能是结束集(b * d)
  3. 用结束集计算起始集
  4. 从步骤 1 中减去步骤 2 中的步骤 3 的值
  5. Step1得到的数补4个0,step2的值不变,step4得到的值补2个0。

现在让我们提出上述步骤并在进入实施部分之前用插图展示它

插图:

Input: x = 1234, y = 5678

Processing: As per above inputs

x = 1234
y = 5678

a = 12, b = 34
c = 56, d = 78

Step 1: a * c = 172     
Step 2: b * d = 2652          
Step 3: (a+b)(c+d) = 134 * 36 = 6164
Step 4: 6164 - 2652 - 172 = 2840
Step 5: 1720000 + 2652 + 284000 = 7006652
Output: 7006652

步骤 5 得到的值实际上是在这两个数字“x”和“y”之间进行标准学校乘法得到的乘积。

1720000 + 2652 + 284000 = 7006652

实施 请注意,不要掌握为该算法制定的公式,而是以这种方式理解它会使它变得更好。

Java
/// Java Program to Implement Karatsuba Algorithm
 
// Importing Random class from java.util packahge
import java.util.Random;
 
// MAin class
class GFG {
 
    // Main driver method
    public static long mult(long x, long y) {
 
        // Checking only if input is within range 
        if (x < 10 && y < 10) {
           
            // Multiplying the inputs entered
            return x * y;
        }
      
        // Declaring variables in order to 
        // Find length of both integer
        // numbers x and y
        int noOneLength = numLength(x);
        int noTwoLength = numLength(y);
 
        // Finding maximum length from both numbers
        // using math library max function
        int maxNumLength
            = Math.max(noOneLength, noTwoLength);
 
        // Rounding up the divided Max length
        Integer halfMaxNumLength
            = (maxNumLength / 2) + (maxNumLength % 2);
 
        // Multiplier
        long maxNumLengthTen
            = (long)Math.pow(10, halfMaxNumLength);
 
        // Compute the expressions
        long a = x / maxNumLengthTen;
        long b = x % maxNumLengthTen;
        long c = y / maxNumLengthTen;
        long d = y % maxNumLengthTen;
 
 
        // Compute all mutilpying variables
        // needed to get the multiplication   
        long z0 = mult(a, c);
        long z1 = mult(a + b, c + d);
        long z2 = mult(b, d);
 
        long ans = (z0 * (long)Math.pow(10, halfMaxNumLength * 2) +
                   ((z1 - z0 - z2) * (long)Math.pow(10, halfMaxNumLength) + z2));
 
        return ans;
 
    }
   
      // Method 1
    // To calculate length of the number
    public static int numLength(long n)
    {
        int noLen = 0;
        while (n > 0) {
            noLen++;
            n /= 10;
        }
 
        // Returning length of number n
        return noLen;
    }
 
     // Method 2
    // Main driver function
    public static void main(String[] args)
    {
        // Showcasing karatsuba multiplication
         
      // Case 1: Big integer lengths
        long expectedProduct = 1234 * 5678;
        long actualProduct = mult(1234, 5678);
 
        // Printing the expected and corresponding actual product
        System.out.println("Expected 1 : " + expectedProduct);
        System.out.println("Actual 1 : " + actualProduct + "\n\n");
       
        assert(expectedProduct == actualProduct);
 
 
        expectedProduct = 102 * 313;
        actualProduct = mult(102, 313);
 
        System.out.println("Expected 2 : " + expectedProduct);
        System.out.println("Actual 2 : " + actualProduct + "\n\n");
         
      assert(expectedProduct == actualProduct);
 
        expectedProduct = 1345 * 63456;
        actualProduct = mult(1345, 63456);
 
        System.out.println("Expected 3 : " + expectedProduct);
        System.out.println("Actual 3 : " + actualProduct + "\n\n");
         
      assert(expectedProduct == actualProduct);       
     
        Integer x = null;
        Integer y = null;
        Integer MAX_VALUE = 10000;
 
        // Boe creating an object of random class
        // inside main() method
        Random r = new Random();
 
        for (int i = 0; i < MAX_VALUE; i++) {
            x = (int) r.nextInt(MAX_VALUE);
            y = (int) r.nextInt(MAX_VALUE);
 
            expectedProduct = x * y;
 
            if (i == 9999) {
               
              // Prove assertions catch the bad stuff.
                expectedProduct = 1;   
            }
            actualProduct = mult(x, y);
 
             // Again printing the expected and
            // corresponding actual product
            System.out.println("Expected: " + expectedProduct);
            System.out.println("Actual: " + actualProduct + "\n\n");
 
            assert(expectedProduct == actualProduct);       
        }
    }
}


输出
Product 1 : 85348320
Product 2 : 21726