Given two polynomials represented by two arrays, write a function that multiplies given two polynomials.
Example:
Input: A[] = {5, 0, 10, 6}
B[] = {1, 2, 4}
Output: prod[] = {5, 10, 30, 26, 52, 24}
The first input array represents "5 + 0x^1 + 10x^2 + 6x^3"
The second array represents "1 + 2x^1 + 4x^2"
And Output is "5 + 10x^1 + 30x^2 + 26x^3 + 52x^4 + 24x^5"
A simple solution is to one by one consider every term of the first polynomial and multiply it with every term of the second polynomial. Following is the algorithm of this simple method.
multiply(A[0..m-1], B[0..n-1])
1) Create a product array prod[] of size m+n-1.
2) Initialize all entries in prod[] as 0.
3) Traverse array A[] and do following for every element A[i]
...(3.a) Traverse array B[] and do following for every element B[j]
prod[i+j] = prod[i+j] + A[i] * B[j]
4) Return prod[].
The following is the implementation of the above algorithm.
C++
#include <iostream>
using namespace std;
int *multiply( int A[], int B[], int m, int n)
{
int *prod = new int [m+n-1];
for ( int i = 0; i<m+n-1; i++)
prod[i] = 0;
for ( int i=0; i<m; i++)
{
for ( int j=0; j<n; j++)
prod[i+j] += A[i]*B[j];
}
return prod;
}
void printPoly( int poly[], int n)
{
for ( int i=0; i<n; i++)
{
cout << poly[i];
if (i != 0)
cout << "x^" << i ;
if (i != n-1)
cout << " + " ;
}
}
int main()
{
int A[] = {5, 0, 10, 6};
int B[] = {1, 2, 4};
int m = sizeof (A)/ sizeof (A[0]);
int n = sizeof (B)/ sizeof (B[0]);
cout << "First polynomial is " ;
printPoly(A, m);
cout <<endl<< "Second polynomial is " ;
printPoly(B, n);
int *prod = multiply(A, B, m, n);
cout <<endl<< "Product polynomial is " ;
printPoly(prod, m+n-1);
return 0;
}
|
Java
class GFG
{
static int [] multiply( int A[], int B[],
int m, int n)
{
int [] prod = new int [m + n - 1 ];
for ( int i = 0 ; i < m + n - 1 ; i++)
{
prod[i] = 0 ;
}
for ( int i = 0 ; i < m; i++)
{
for ( int j = 0 ; j < n; j++)
{
prod[i + j] += A[i] * B[j];
}
}
return prod;
}
static void printPoly( int poly[], int n)
{
for ( int i = 0 ; i < n; i++)
{
System.out.print(poly[i]);
if (i != 0 )
{
System.out.print( "x^" + i);
}
if (i != n - 1 )
{
System.out.print( " + " );
}
}
}
public static void main(String[] args)
{
int A[] = { 5 , 0 , 10 , 6 };
int B[] = { 1 , 2 , 4 };
int m = A.length;
int n = B.length;
System.out.println( "First polynomial is n" );
printPoly(A, m);
System.out.println( "nSecond polynomial is n" );
printPoly(B, n);
int [] prod = multiply(A, B, m, n);
System.out.println( "nProduct polynomial is n" );
printPoly(prod, m + n - 1 );
}
}
|
Python3
def multiply(A, B, m, n):
prod = [ 0 ] * (m + n - 1 );
for i in range (m):
for j in range (n):
prod[i + j] + = A[i] * B[j];
return prod;
def printPoly(poly, n):
for i in range (n):
print (poly[i], end = "");
if (i ! = 0 ):
print ( "x^" , i, end = "");
if (i ! = n - 1 ):
print ( " + " , end = "");
A = [ 5 , 0 , 10 , 6 ];
B = [ 1 , 2 , 4 ];
m = len (A);
n = len (B);
print ( "First polynomial is " );
printPoly(A, m);
print ( "\nSecond polynomial is " );
printPoly(B, n);
prod = multiply(A, B, m, n);
print ( "\nProduct polynomial is " );
printPoly(prod, m + n - 1 );
|
C#
using System;
class GFG
{
static int [] multiply( int []A, int []B,
int m, int n)
{
int [] prod = new int [m + n - 1];
for ( int i = 0; i < m + n - 1; i++)
{
prod[i] = 0;
}
for ( int i = 0; i < m; i++)
{
for ( int j = 0; j < n; j++)
{
prod[i + j] += A[i] * B[j];
}
}
return prod;
}
static void printPoly( int []poly, int n)
{
for ( int i = 0; i < n; i++) {
Console.Write(poly[i]);
if (i != 0) {
Console.Write( "x^" + i);
}
if (i != n - 1) {
Console.Write( " + " );
}
}
}
public static void Main(String[] args)
{
int []A = {5, 0, 10, 6};
int []B = {1, 2, 4};
int m = A.Length;
int n = B.Length;
Console.WriteLine( "First polynomial is n" );
printPoly(A, m);
Console.WriteLine( "nSecond polynomial is n" );
printPoly(B, n);
int [] prod = multiply(A, B, m, n);
Console.WriteLine( "nProduct polynomial is n" );
printPoly(prod, m + n - 1);
}
}
|
PHP
<?php
function multiply( $A , $B , $m , $n )
{
$prod = array_fill (0, $m + $n - 1, 0);
for ( $i = 0; $i < $m ; $i ++)
{
for ( $j = 0; $j < $n ; $j ++)
$prod [ $i + $j ] += $A [ $i ] * $B [ $j ];
}
return $prod ;
}
function printPoly( $poly , $n )
{
for ( $i = 0; $i < $n ; $i ++)
{
echo $poly [ $i ];
if ( $i != 0)
echo "x^" . $i ;
if ( $i != $n - 1)
echo " + " ;
}
}
$A = array (5, 0, 10, 6);
$B = array (1, 2, 4);
$m = count ( $A );
$n = count ( $B );
echo "First polynomial is \n" ;
printPoly( $A , $m );
echo "\nSecond polynomial is \n" ;
printPoly( $B , $n );
$prod = multiply( $A , $B , $m , $n );
echo "\nProduct polynomial is \n" ;
printPoly( $prod , $m + $n -1);
?>
|
Javascript
<script>
function multiply(A, B, m, n){
var prod = [];
for ( var i = 0; i < m + n - 1; i++) prod[i] = 0;
for ( var i = 0; i < m ; i++){
for ( var j = 0; j < n ; j++)
prod[i + j] += A[i] * B[j];
}
return prod;
}
function printPoly(poly, n){
let ans= '' ;
for ( var i = 0; i < n ; i++){
ans += poly[i];
if (i != 0)
ans += "x^ " +i;
if (i != n - 1)
ans += " + " ;
}
document.write(ans)
}
A = [5, 0, 10, 6];
let B = [1, 2, 4];
let m = (A).length;
let n = (B).length;
document.write( "First polynomial is " + "<br>" );
printPoly(A, m);
document.write( "<br>" );
document.write( "Second polynomial is " + "<br>" );
printPoly(B, n);
let prod = multiply(A, B, m, n);
document.write( "<br>" );
document.write( "Product polynomial is " + "<br>" );
printPoly(prod, m+n-1);
</script>
|
Output
First polynomial is 5 + 0x^1 + 10x^2 + 6x^3
Second polynomial is 1 + 2x^1 + 4x^2
Product polynomial is 5 + 10x^1 + 30x^2 + 26x^3 + 52x^4 + 24x^5
The time complexity of the above solution is O(mn). If the size of two polynomials same, then the time complexity is O(n2).
Auxiliary Space: O(m + n)
Can we do better?
There are methods to do multiplication faster than O(n2) time. These methods are mainly based on divide and conquer. Following is one simple method that divides the given polynomial (of degree n) into two polynomials one containing lower degree terms(lower than n/2) and the other containing higher degree terms (higher than or equal to n/2)
Let the two given polynomials be A and B.
For simplicity, Let us assume that the given two polynomials are of
same degree and have degree in powers of 2, i.e., n = 2i
The polynomial 'A' can be written as A0 + A1*xn/2
The polynomial 'B' can be written as B0 + B1*xn/2
For example 1 + 10x + 6x2 - 4x3 + 5x4 can be
written as (1 + 10x) + (6 - 4x + 5x2)*x2
A * B = (A0 + A1*xn/2) * (B0 + B1*xn/2)
= A0*B0 + A0*B1*xn/2 + A1*B0*xn/2 + A1*B1*xn
= A0*B0 + (A0*B1 + A1*B0)xn/2 + A1*B1*xn
So the above divide and conquer approach requires 4 multiplications and O(n) time to add all 4 results. Therefore the time complexity is T(n) = 4T(n/2) + O(n). The solution of the recurrence is O(n2) which is the same as the above simple solution.
The idea is to reduce the number of multiplications to 3 and make the recurrence as T(n) = 3T(n/2) + O(n)
How to reduce the number of multiplications?
This requires a little trick similar to Strassen’s Matrix Multiplication. We do the following 3 multiplications.
X = (A0 + A1)*(B0 + B1) // First Multiplication
Y = A0B0 // Second
Z = A1B1 // Third
The missing middle term in above multiplication equation A0*B0 + (A0*B1 +
A1*B0)xn/2 + A1*B1*xn can obtained using below.
A0B1 + A1B0 = X - Y - Z
In-Depth Explanation
Conventional polynomial multiplication uses 4 coefficient multiplications:
(ax + b)(cx + d) = acx2 + (ad + bc)x + bd
However, notice the following relation:
(a + b)(c + d) = ad + bc + ac + bd
The rest of the two components are exactly the middle coefficient for the product of two polynomials. Therefore, the product can be computed as:
(ax + b)(cx + d) = acx2 +
((a + b)(c + d) - ac - bd )x + bd
Hence, the latter expression has only three multiplications.
So the time taken by this algorithm is T(n) = 3T(n/2) + O(n)
The solution of the above recurrence is O(nLg3) which is better than O(n2).
We will soon be discussing the implementation of the above approach.
There is an O(nLogn) algorithm also that uses Fast Fourier Transform to multiply two polynomials (Refer to this and this for details)
Last Updated :
16 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...