برنامه ضرب چند جمله ای ها — راهنمای کاربردی
پیش از این، در مطلب «کد جمع کردن چند جمله ای ها — راهنمای کاربردی» به روش جمع کردن دو چند جملهای و پیادهسازی این روش در زبانهای برنامهنویسی گوناگون پرداخته شد. در این مطلب، روش و برنامه ضرب چند جمله ای ها در زبانهای برنامهنویسی گوناگون ارائه شده است. در ادامه، مساله تعریف و سپس حل میشود. دو چند جملهای که به وسیله دو آرایه نمایش داده میشوند، ارائه شدهاند. هدف، نوشتن تابعی است که دو چند جملهای را در یکدیگر ضرب کند. به عنوان مثال، داریم:
ورودی:
A[] = {5, 0, 10, 6}
B[] = {1, 2, 4}
خروجی:
prod[] = {5, 10, 30, 26, 52, 24}
اولین آرایه ورودی نشانگر چند جملهای است. دومین آرایه ورودی نشانگر چند جملهای «» است. یک راهکار ساده برای حل مساله بیان شده آن است که هر عبارت از اولین چند جملهای در نظر گرفته و در هر عبارت از دومین چند جملهای ضرب شود. در ادامه، الگوریتم این روش ساده آمده است.
ضرب ([A[0..m-1], B[0..n01)
- ساخت آرایه حاصل ضرب به صورت []prod با اندازه m+n+1
- مقداردهی اولیه همه ورودیها در []prod با صفر
- پیمایش آرایه []A و انجام اقدامات زیر برای هر عنصر [A[i
- پیمایش آرایه []B و انجام اقدامات زیر برای هر عنصر [B[j
- [prod[i+j] = prod[i+j] + A[i] * B[j
- پیمایش آرایه []B و انجام اقدامات زیر برای هر عنصر [B[j
- بازگرداندن []prod به عنوان خروجی.
برنامه ضرب دو چند جملهای در ++C
1// Simple C++ program to multiply two polynomials
2#include <iostream>
3using namespace std;
4
5// A[] represents coefficients of first polynomial
6// B[] represents coefficients of second polynomial
7// m and n are sizes of A[] and B[] respectively
8int *multiply(int A[], int B[], int m, int n)
9{
10 int *prod = new int[m+n-1];
11
12 // Initialize the porduct polynomial
13 for (int i = 0; i<m+n-1; i++)
14 prod[i] = 0;
15
16 // Multiply two polynomials term by term
17
18 // Take ever term of first polynomial
19 for (int i=0; i<m; i++)
20 {
21 // Multiply the current term of first polynomial
22 // with every term of second polynomial.
23 for (int j=0; j<n; j++)
24 prod[i+j] += A[i]*B[j];
25 }
26
27 return prod;
28}
29
30// A utility function to print a polynomial
31void printPoly(int poly[], int n)
32{
33 for (int i=0; i<n; i++)
34 {
35 cout << poly[i];
36 if (i != 0)
37 cout << "x^" << i ;
38 if (i != n-1)
39 cout << " + ";
40 }
41}
42
43// Driver program to test above functions
44int main()
45{
46 // The following array represents polynomial 5 + 10x^2 + 6x^3
47 int A[] = {5, 0, 10, 6};
48
49 // The following array represents polynomial 1 + 2x + 4x^2
50 int B[] = {1, 2, 4};
51 int m = sizeof(A)/sizeof(A[0]);
52 int n = sizeof(B)/sizeof(B[0]);
53
54 cout << "First polynomial is n";
55 printPoly(A, m);
56 cout << "nSecond polynomial is n";
57 printPoly(B, n);
58
59 int *prod = multiply(A, B, m, n);
60
61 cout << "nProduct polynomial is n";
62 printPoly(prod, m+n-1);
63
64 return 0;
65}
برنامه ضرب دو چند جملهای در جاوا
1// Java program to multiply two polynomials
2class GFG
3{
4
5 // A[] represents coefficients
6 // of first polynomial
7 // B[] represents coefficients
8 // of second polynomial
9 // m and n are sizes of A[] and B[] respectively
10 static int[] multiply(int A[], int B[],
11 int m, int n)
12 {
13 int[] prod = new int[m + n - 1];
14
15 // Initialize the porduct polynomial
16 for (int i = 0; i < m + n - 1; i++)
17 {
18 prod[i] = 0;
19 }
20
21 // Multiply two polynomials term by term
22 // Take ever term of first polynomial
23 for (int i = 0; i < m; i++)
24 {
25 // Multiply the current term of first polynomial
26 // with every term of second polynomial.
27 for (int j = 0; j < n; j++)
28 {
29 prod[i + j] += A[i] * B[j];
30 }
31 }
32
33 return prod;
34 }
35
36 // A utility function to print a polynomial
37 static void printPoly(int poly[], int n)
38 {
39 for (int i = 0; i < n; i++)
40 {
41 System.out.print(poly[i]);
42 if (i != 0)
43 {
44 System.out.print("x^" + i);
45 }
46 if (i != n - 1)
47 {
48 System.out.print(" + ");
49 }
50 }
51 }
52
53 // Driver code
54 public static void main(String[] args)
55 {
56 // The following array represents
57 // polynomial 5 + 10x^2 + 6x^3
58 int A[] = {5, 0, 10, 6};
59
60 // The following array represents
61 // polynomial 1 + 2x + 4x^2
62 int B[] = {1, 2, 4};
63 int m = A.length;
64 int n = B.length;
65
66 System.out.println("First polynomial is n");
67 printPoly(A, m);
68 System.out.println("nSecond polynomial is n");
69 printPoly(B, n);
70
71 int[] prod = multiply(A, B, m, n);
72
73 System.out.println("nProduct polynomial is n");
74 printPoly(prod, m + n - 1);
75 }
76}
77
78// This code contributed by Rajput-Ji
برنامه ضرب دو چند جملهای در پایتون ۳
1# Simple Python3 program to multiply two polynomials
2
3# A[] represents coefficients of first polynomial
4# B[] represents coefficients of second polynomial
5# m and n are sizes of A[] and B[] respectively
6def multiply(A, B, m, n):
7
8 prod = [0] * (m + n - 1);
9
10 # Multiply two polynomials term by term
11
12 # Take ever term of first polynomial
13 for i in range(m):
14
15 # Multiply the current term of first
16 # polynomial with every term of
17 # second polynomial.
18 for j in range(n):
19 prod[i + j] += A[i] * B[j];
20
21 return prod;
22
23# A utility function to print a polynomial
24def printPoly(poly, n):
25
26 for i in range(n):
27 print(poly[i], end = "");
28 if (i != 0):
29 print("x^", i, end = "");
30 if (i != n - 1):
31 print(" + ", end = "");
32
33# Driver Code
34
35# The following array represents
36# polynomial 5 + 10x^2 + 6x^3
37A = [5, 0, 10, 6];
38
39# The following array represents
40# polynomial 1 + 2x + 4x^2
41B = [1, 2, 4];
42m = len(A);
43n = len(B);
44
45print("First polynomial is ");
46printPoly(A, m);
47print("\nSecond polynomial is ");
48printPoly(B, n);
49
50prod = multiply(A, B, m, n);
51
52print("\nProduct polynomial is ");
53printPoly(prod, m+n-1);
54
55# This code is contributed by chandan_jnu
برنامه ضرب دو چند جملهای در #C
1// C# program to multiply two polynomials
2using System;
3
4class GFG
5{
6
7 // A[] represents coefficients
8 // of first polynomial
9 // B[] represents coefficients
10 // of second polynomial
11 // m and n are sizes of A[]
12 // and B[] respectively
13 static int[] multiply(int []A, int []B,
14 int m, int n)
15 {
16 int[] prod = new int[m + n - 1];
17
18 // Initialize the porduct polynomial
19 for (int i = 0; i < m + n - 1; i++)
20 {
21 prod[i] = 0;
22 }
23
24 // Multiply two polynomials term by term
25 // Take ever term of first polynomial
26 for (int i = 0; i < m; i++)
27 {
28 // Multiply the current term of first polynomial
29 // with every term of second polynomial.
30 for (int j = 0; j < n; j++)
31 {
32 prod[i + j] += A[i] * B[j];
33 }
34 }
35
36 return prod;
37 }
38
39 // A utility function to print a polynomial
40 static void printPoly(int []poly, int n)
41 {
42 for (int i = 0; i < n; i++) {
43 Console.Write(poly[i]);
44 if (i != 0) {
45 Console.Write("x^" + i);
46 }
47 if (i != n - 1) {
48 Console.Write(" + ");
49 }
50 }
51 }
52
53 // Driver code
54 public static void Main(String[] args)
55 {
56
57 // The following array represents
58 // polynomial 5 + 10x^2 + 6x^3
59 int []A = {5, 0, 10, 6};
60
61 // The following array represents
62 // polynomial 1 + 2x + 4x^2
63 int []B = {1, 2, 4};
64 int m = A.Length;
65 int n = B.Length;
66
67 Console.WriteLine("First polynomial is n");
68 printPoly(A, m);
69 Console.WriteLine("nSecond polynomial is n");
70 printPoly(B, n);
71
72 int[] prod = multiply(A, B, m, n);
73
74 Console.WriteLine("nProduct polynomial is n");
75 printPoly(prod, m + n - 1);
76 }
77}
78
79// This code has been contributed by 29AjayKumar
برنامه ضرب دو چند جملهای در PHP
1<?php
2// Simple PHP program to multiply two polynomials
3
4// A[] represents coefficients of first polynomial
5// B[] represents coefficients of second polynomial
6// m and n are sizes of A[] and B[] respectively
7function multiply($A, $B, $m, $n)
8{
9 $prod = array_fill(0, $m + $n - 1, 0);
10
11 // Multiply two polynomials term by term
12
13 // Take ever term of first polynomial
14 for ($i = 0; $i < $m; $i++)
15 {
16 // Multiply the current term of first
17 // polynomial with every term of
18 // second polynomial.
19 for ($j = 0; $j < $n; $j++)
20 $prod[$i + $j] += $A[$i] * $B[$j];
21 }
22
23 return $prod;
24}
25
26// A utility function to print a polynomial
27function printPoly($poly, $n)
28{
29 for ($i = 0; $i < $n; $i++)
30 {
31 echo $poly[$i];
32 if ($i != 0)
33 echo "x^" . $i;
34 if ($i != $n - 1)
35 echo " + ";
36 }
37}
38
39// Driver Code
40
41// The following array represents
42// polynomial 5 + 10x^2 + 6x^3
43$A = array(5, 0, 10, 6);
44
45// The following array represents
46// polynomial 1 + 2x + 4x^2
47$B = array(1, 2, 4);
48$m = count($A);
49$n = count($B);
50
51echo "First polynomial is \n";
52printPoly($A, $m);
53echo "\nSecond polynomial is \n";
54printPoly($B, $n);
55
56$prod = multiply($A, $B, $m, $n);
57
58echo "\nProduct polynomial is \n";
59printPoly($prod, $m+$n-1);
60
61// This code is contributed by chandan_jnu
62?>
خروجی
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
پیچیدگی زمانی
پیچیدگی زمانی راهکار بالا برابر با (O(mn است. اگر اندازه دو چند جملهای برابر باشد، پیچیدگی زمانی از درجه (O(n2 خواهد بود. راهکارهایی برای انجام ضرب دو چند جمله ای با سرعتی بیش از (O(n2 وجود دارد. این روشها معمولا بر مبنای الگوریتم «تقسیم و حل» (Divide and Conquer) هستند.
ضرب چند جمله ای ها بر مبنای الگوریتم تقسیم و حل
روشی که در ادامه آمده، راهکاری ساده است که چند جملهای داده شده (از درجه n را) را در دو چند جملهای که یکی دارای عبارات مرتبه پایینتر (کمتر از ) و دیگری شامل درجات بیشتر (بزرگتر یا مساوی ) است، ضرب میکند.
الگوریتم انجام این کار در ادامه ارائه شده است.
- فرض میشود دو چند جملهای A و B داده شدهاند. برای سادگی، فرض میشود که هر دو چند جملهای دارای مرتبه مشابهی هستند و مرتبه آنها از توان ۲، یعنی n = 2i. است
- چند جملهای A را میتوان به صورت نوشت.
- چند جملهای B را میتوان به صورت نوشت.
- برای مثال، را میتوان به صورت نوشت.
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
رویکرد تقسیم و حل ارائه شده در بالا، نیازمند ۴ ضرب و زمان (O(n برای جمع کردن همه ۴ نتیجه است. بنابراین، پیچیدگی زمانی آن برابر با خواهد بود. راهکار، بازگشت از مرتبه (O(n2 است که این عدد برابر با پیچیدگی زمانی راهکار ساده مطرح شده در بالا است. اکنون ایده موجود برای حل این مساله آن است که تعداد ضربها به ۳ تا کاهش پیدا کند و بازگشت به صورت (T(n) = 3T(n/2) + O(n باشد.
روش کاهش تعداد ضربها
این کار نیاز به ترفند کوچکی دارد که مشابه با ضرب ماتریسها با «الگوریتم استراسن» (Strassen Algorithm) است. سه ضرب زیر انجام میشوند.
X = (A0 + A1)*(B0 + B1) // اولین ضرب
Y = A0B0 // دومین ضرب
Z = A1B1 // سومین ضرب
عبارت ناموجود در ضرب بالا برابر است با:
A0*B0 + (A0*B1 + A1*B0)xn/2 + A1*B1*xn
که میتوان آن را به صورت زیر نوشت.
A0B1 + A1B0 = X - Y - Z
توضیح دقیق
روش مرسوم ضرب چند جملهایها، از ۴ ضریب ضرب استفاده میکند.
(ax + b)(cx + d) = acx2 + (ad + bc)x + bd
اگرچه، رابطه زیر شایان توجه است:
1(a + b)(c + d) = ad + bc + ac + bd
باقیمانده دو مولفه، دقیقا ضریب میانی برای دو چند جملهای هستند. بنابراین، ضرب را میتوان به شیوه زیر محاسبه کرد.
1(ax + b)(cx + d) = acx2 +
2((a + b)(c + d) , ac , bd )x + bd
بنابراین، عبارت دوم تنها سه ضرب دارد. در نتیجه، زمانی که توسط این الگوریتم گرفته میشود برابر با است.