Large Integer Multiplication "Divide and Conquer" and "Cyclic Violence"

Keywords: Java

Preface

Today I brushed a very interesting interview question. It feels very interesting to share with you.

Title Description

There are two very large integers represented by strings, and their product is also represented by strings. You cannot use the large integer type that comes with the system.

Input Description:
Two space-delimited strings representing two large integers of input
Output description:
Input product, expressed as a string

Example 1

input
72106547548473106236 982161082972751393
output
70820244829634538040848656466105986748

Thinking analysis

For example, x=1234,y=567

  • 1. Divide x into two halves, a = 12 b = 34
  • (2) Divide y into two halves, C = 5 d = 67
  • (3) xy = 12102 + 34 (5102 + 67) = (a102 + b) (c102 + d) = AC104 + ad102 + B C102 + B D
  • (4) The results of recursion (a c), (a d), (b c), (b d) are directly multiplied if a,b, C and D are small enough. Otherwise, repeat the first step and continue to split a,b, C and d until the result can be directly calculated, the recursion ends and the backtracking begins.

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner sca = new Scanner(System.in);
        String x = sca.nextLine();
        String y = sca.nextLine();
        System.out.println(f(x,y));
    }

    //Divide and Conquer
    public static Long f(String x,String y){
        String a = x.substring(0, x.length()/2);
        String b = x.substring(x.length()/2);
        String c = y.substring(0, y.length()/2);
        String d = y.substring(y.length()/2);
        int n = b.length();
        int m = d.length();
        if(x.length()<=4 && y.length()<=4){
            return (long) (Integer.parseInt(x)*Integer.parseInt(y));
        }
        if(x.length()>4 && y.length()<=4){
            return (long) (f(a,y)*Math.pow(10, n)+f(b,y));
        }
        if(y.length()>4 && x.length()<=4){
            return (long) (f(c,x)*Math.pow(10, m)+f(d,x));
        }else{
            return (long) (f(a,c)*Math.pow(10, n+m)+f(a,d)*Math.pow(10, n)+f(b,c)*Math.pow(10, m)+f(b,d));
        }
    }
}

In this way, the time complexity is o (log2max (n, m), where n is the length of x and M is the length of y.

But when the final product exceeds the long type, it will still be wrong.

I never thought of a good way to solve it completely. Baidu tried several people's java code, and the results were all false positives. Some even received large integers with long variables, and they were wrong directly. None of them was right. The visits were so high. Zhenshui, ah,,,,,,,,

Then I think of another way to solve this problem perfectly. The time complexity is o (n2):

Cyclic Violence Act:

  • (1) To split two strings into int-type arrays

  • (2) Multiplying every number in intx [] by every number in inty [] is the traditional process of hand-counting on paper and storing the result in another array.

  • If the multiplication of two digits is two digits, add the number of ten digits to the high position.

At the end of the loop, the product of two large numbers is stored digitally in the array.

This method applies to all multiplications of large numbers.

The java code is as follows

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner sca = new Scanner(System.in);
        String x = sca.nextLine();
        String y = sca.nextLine();
        System.out.println(f(x,y));
    }
    public static String f(String x,String y){
        int[] intx = new int[x.length()];
        int[] inty = new int[y.length()];
        int[] intsum = new int[x.length()+y.length()];

        for (int i = 0; i < x.length(); i++) {
            intx[x.length()-1-i] = Integer.parseInt(x.substring(i, i+1));
        }
        for (int i = 0; i < y.length(); i++) {
            inty[y.length()-1-i] = Integer.parseInt(y.substring(i, i+1));
        }
        for (int i = 0; i < intx.length; i++) {
            for (int j = 0; j < inty.length; j++) {
                intsum[i+j] += intx[i]*inty[j];
            }
            for (int j = 0; j < intsum.length-1; j++) {
                if(intsum[j]>9){
                    intsum[j+1]+=intsum[j]/10;
                    intsum[j] = intsum[j]%10;
                }
            }
        }
        String str = "";
        boolean t = false;
        for (int i = intsum.length-1; i >=0; i--) {
            if(intsum[i]!=0) t = true;
            if(t) str = str+intsum[i];
        }
        return str;
    }
}

Hope you can give more advice!

Posted by BulldogGC on Sat, 11 May 2019 15:34:26 -0700