Java 实现Schonhage-Strassen乘法算法来计算两个数的乘积

Java 实现Schonhage-Strassen乘法算法来计算两个数的乘积

当我们需要乘以大的小数时,Schonhage-Strassen算法非常有用。由于Java支持1018位整数大小,如果我们需要乘以超过1018位的数字,我们需要使用Schonhage-Strassen算法,因为它是最快的乘法算法之一。

它使用两个数字的基本乘法规则。它首先执行线性卷积,然后进行进位以获得最终结果。

问题陈述 - 我们已经给出了mul1和mul2两个大的十进制数,并且需要实现Schonhage-Strassen算法来计算两个数的乘积。

示例

输入

mul1 = 320;  = 760;

输出

243200

描述 - 它已经乘以了这两个数字。

输入

mul1 = 32012233;  = 76031232;

输出

1612188928

解释 - 它对两个大的十进制数进行了乘法运算。

方法1

在这种方法中,我们首先编写一个函数来计算线性卷积。然后,我们将以这样的方式添加所有线性卷积的结果值,以便我们可以前置进位添加到下一个元素中。

这里,我们解释了一种用于编写Schonhage-Strassen算法的Java代码的逐步算法。

算法

步骤1 - 执行perfromMultiplication()函数。在该函数中,首先执行getLinConvolution()函数。

步骤2 - 在getLinConvolution()函数中,使用findTotalDigits()函数计算给定数字的总位数。

步骤2.1 - 在findTotalDigits()函数中,将’cnt’初始化为零以存储数字的总位数。

步骤2.2 - 在num_int大于零之前进行迭代。

步骤2.3 - 在循环中,将num_int除以10。还要增加cnt的值1。

步骤2.4 - 最后,返回’cnt’的值。

步骤3 - 定义’tmp_mul1’并存储mul1数的值。还定义lcon_len变量以存储我们需要使用的数组的长度,以存储线性卷积。

步骤4 - 开始遍历mul2的数字。在循环中,将tmp_mul1的值存储到mul1,然后使用另一个嵌套循环来遍历mul1的数字。

步骤5 - 通过将(mul2 % 10) * (mul1 % 10)添加到当前值,更新数组中的(p + q)索引处的值。

步骤6 - 现在,我们有了线性卷积,需要对列表进行进位操作。因此,调用addCarry()函数。

步骤7 - 初始化用于存储乘积、进位和基数的变量。

步骤8 - 开始遍历列表。将’C’添加到列表中第i个索引值中。

步骤9 - 在’predocut_res’中添加B * (linConvoList[i] % 10),其中B是基数值。

步骤10 - 将linConvoList除以10,并使用它更新’C’的值。

步骤11 - 将基数乘以10。

步骤12 - 完成所有循环迭代后,将C*B添加到乘积结果中,以将最终进位添加到列表中。最后,打印出两个十进制数的乘积结果。

示例

import java.io.*;
public class Main {
   // for storing the LinearConvolution
   static int[] linConvoList;
   // to store length of the LinearConvolution
   static int lcon_len;
   // function to count total digits in given number
   static int findTotalDigits(long num_int) {
      // Initial digits
      int cnt = 0;
      // Make iterations until num_int is greater than zero
      while (num_int > 0) {
         num_int /= 10;
         cnt++;
      }
      // return cnt value
      return cnt;
   }
   static void getLinConvolution(long mul1, long mul2) {
      // count digits in mul1
      int mul1Digits = findTotalDigits(mul1);
      // count digits in mul2
      int mul2Digits = findTotalDigits(mul2);
      // to store temporary value of mul1
      long tmp_mul1 = mul1;
      // Initialize the length of the linear convolution
      lcon_len = mul1Digits + mul2Digits - 1;
      // Initialize the list
      linConvoList = new int[lcon_len];
      // Filling the linConvoList array
      for (int p = 0; p < mul2Digits; p++, mul2 /= 10) {
         // Reset the value of mul1 for each iteration of mul2
         mul1 = tmp_mul1;
         for (int q = 0; q < mul1Digits; q++, mul1 /= 10) {
            // multiply digit of mul1 and mul2
            linConvoList[p + q] += (int) ((mul2 % 10) * (mul1 % 10));
         }
      }
      System.out.print("The values stored in the linear convolution array are: ");
      for (int p = lcon_len - 1; p >= 0; p--) {
         System.out.print(linConvoList[p] + " ");
      }
      System.out.println();
   }
   static void addCarry() {
      // initialize product to 0
      long product_res = 0;
      // Initialize variables for carry and base
      int C = 0, B = 1;
      // Traverse the list
      for (int i = 0; i < lcon_len; i++) {
         linConvoList[i] += C;
         // performing operations
         product_res = product_res + (B * (linConvoList[i] % 10));
         // Divide the linConvoList[i] by 10 to get carry
         C = linConvoList[i] / 10;
         // Multiply the base by 10
         B *= 10;
      }
      // Add the final carry if it exists
      product_res += C * B;
      System.out.println("\nThe Product of mul1 and mul2 is: " + product_res+ "\n");
   }
   // Multiplication starts here
   static void performMultiplication(long mul1, long mul2) {
      // To get the LinearConvolution
      getLinConvolution(mul1, mul2);
      // Add carry to the LinearConvolution
      addCarry();
   }
   // Driver method
   public static void main(String[] args) {
      long mul1, mul2;
      // long numbers to multiply
      mul1 = 320;
      mul2 = 760;
      performMultiplication(mul1, mul2);
   }
}

输出

The values stored in the linear convolution array are: 21 32 12 0 0 
The Product of mul1 and mul2 is: 243200

时间复杂度: - O(M + N),其中M是mul1中总数字数,N是mul2中总数字数。

空间复杂度: - O(M + N),因为需要存储线性卷积。

在代码中,程序员可以观察到Schonhage-Strassen算法与我们在数学中所做的普通乘法相同。程序员可以观察线性卷积的结果来理解算法。

此外,程序员应该尝试编写算法来对两个大数进行求和,以进行更多的练习。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程