【Weiss】【第03章】练习3.7:有序多项式相乘
【練習3.7】
編寫一個函數將兩個多項式相乘,用一個鏈表實現。你必須保證輸出的多項式按冪次排列,并且任意冪次最多只有一項。
a.給出以O(M2N2)時間求解該問題的算法。
b.寫一個以O(M2N)時間執行乘法的程序,其中M≤N。
c.寫一個以O(MNlog(MN))時間執行乘法的程序。
d.上面哪個時間界最好?
?
?
Answer:
【a】.將兩鏈表元素兩兩相乘并列出,從第一項開始,依次與其后的所有項比較,如相等則合并。
合并完成后,每次找出冪次最小的項,插入鏈表。(最原始的方法)
【b】.M≤1時,方法易知。
M≥2時,每次將長度為M的鏈表的一項,與另一鏈表的所有項相乘,每次一組N個有序的多項式元素。
對于每兩組上式的N個多項式元素,基本按練習3.5有序鏈表求并的算法(除冪次相同需將系數相加)操作。
求并算法時間復雜度O(M+N),故該算法復雜度為
(乘法時間)O(MN)+(求并時間)O((N+N)+(2N+N)+(3N+N)+……+(MN+N))=O(M2N)
【詳情見代碼】
【c】.同a先將兩鏈表元素兩兩相乘并列出,對MN項元素進行O(NlogN)的排序
排序完成后,遍歷代碼,合并同冪次項,最后全部插入鏈表。時間復雜度為:
(乘法時間)O(MN)+(排序時間)O(MNlogMN)+(合并同類項時間)O(MN)=O(MNlogMN)
【詳見代碼】
?
代碼部分,首先是測試代碼,b和c的測試代碼寫在一起了
1 #include <iostream> 2 #include "linklist.h" 3 using linklist::List; 4 using namespace std; 5 int main(void) 6 { 7 //測試多項式加法 8 List<Poly> a; 9 a.additem(Poly(3, 1)); 10 a.additem(Poly(1, 2)); 11 a.additem(Poly(4, 3)); 12 a.additem(Poly(7, 4)); 13 a.additem(Poly(2, 5)); 14 cout << " ( " << flush; 15 a.traverse(); 16 cout << ") +\n" << flush; 17 List<Poly> b; 18 b.additem(Poly(5, 2)); 19 b.additem(Poly(2, 3)); 20 b.additem(Poly(1, 5)); 21 b.additem(Poly(3, 7)); 22 b.additem(Poly(1, 11)); 23 cout << " ( " << flush; 24 b.traverse(); 25 cout << ") =\n" << flush; 26 27 List<Poly> answer = linklist::polymulti_seq(a, b); 28 List<Poly> another = linklist::polymulti_sort(a, b); 29 cout << "\n ( " << flush; 30 answer.traverse(); 31 cout << ") \n" << flush; 32 33 cout << "\n ( " << flush; 34 another.traverse(); 35 cout << ") \n" << flush; 36 system("pause"); 37 } View Code實現部分,首先需在poly.h中重載多項式元素的乘法運算符
1 //練習3.7新增,多項式元素乘法* 2 Poly operator*(const Poly& poly1, const Poly& poly2) 3 { 4 Poly answer; 5 answer.coefficient = poly1.coefficient*poly2.coefficient; 6 answer.exponent = poly1.exponent + poly2.exponent; 7 return answer; 8 }然后是小題b代碼,包括習題3.5求并成員函數的模板特例化的輔助函數及主相乘算法
1 //練習3.7b新增,將3.5求并的成員函數特例化 2 template <> void List<Poly>::join(List<Poly> inorder) 3 { 4 Node<Poly>* curr = front; 5 Node<Poly>* prev = nullptr; 6 Node<Poly>* curr2 = inorder.front; 7 while (curr != nullptr && curr2 != nullptr) 8 { 9 if (curr->data < curr2->data) 10 { 11 prev = curr; 12 curr = curr->next; 13 } 14 else if (curr2->data < curr->data) 15 { 16 additem(curr2->data, prev); 17 if (prev == nullptr) 18 prev = front; 19 else 20 prev = prev->next; 21 curr2 = curr2->next; 22 } 23 else 24 { 25 //對比3.5唯一增加語句 26 //當兩元素冪次相等時,原鏈表與新鏈表的多項式系數相加并將指針后移 27 curr->data = curr->data + curr2->data; 28 prev = curr; 29 curr = curr->next; 30 curr2 = curr2->next; 31 } 32 } 33 while (curr2 != nullptr) 34 { 35 additem(curr2->data, prev); 36 if (prev == nullptr) 37 prev = front; 38 else 39 prev = prev->next; 40 curr2 = curr2->next; 41 } 42 } 43 44 //練習3.7b新增,以O(M2N)時間執行多項式乘法 45 List<Poly> polymulti_seq(const List<Poly> &inorder_a, const List<Poly> &inorder_b) 46 { 47 //保證首鏈表長度較小 48 if (inorder_a.size() > inorder_b.size()) 49 return polymulti_seq(inorder_b, inorder_a); 50 else 51 { 52 List<Poly> answer; 53 for (Node<Poly>* iter_a = inorder_a.begin(); iter_a != nullptr; iter_a = iter_a->next) 54 { 55 //用較短鏈表中每一個元素乘較長鏈表,得到臨時鏈表 56 { 57 List<Poly> temp; 58 for (Node<Poly>* iter_b = inorder_b.begin(); iter_b != nullptr; iter_b = iter_b->next) 59 temp.additem(iter_a->data * iter_b->data); 60 answer.join(temp); 61 } 62 } 63 return answer; 64 } 65 }然后為c小題算法,調用了標準庫中的快排,需要#include<algorithm>
1 //練習3.7c新增,以O(MNlogMN)時間執行多項式乘法 2 List<Poly> polymulti_sort(const List<Poly> &inorder_a, const List<Poly> &inorder_b) 3 { 4 unsigned maxsize = inorder_a.size() * inorder_b.size(); 5 //申請M*N大小的數組 6 Poly* temp_array = new Poly[maxsize]; 7 unsigned int index = 0; 8 //依次對鏈表每兩個節點元素相乘并放在數組中 9 for (Node<Poly>* iter_a = inorder_a.begin(); iter_a != nullptr; iter_a = iter_a->next) 10 for (Node<Poly>* iter_b = inorder_b.begin(); iter_b != nullptr; iter_b = iter_b->next) 11 temp_array[index++] = iter_a->data*iter_b->data; 12 //對數組進行升序快排 13 sort(&temp_array[0], &temp_array[--index]); 14 List<Poly> answer; 15 //單次遍歷數組,合并同類項 16 for (index = 1; index < maxsize; ++index) 17 { 18 if (temp_array[index] == temp_array[index - 1]) 19 temp_array[index] = temp_array[index - 1] + temp_array[index]; 20 else 21 answer.additem(temp_array[index - 1]); 22 } 23 answer.additem(temp_array[index - 1]); 24 delete[] temp_array; 25 return answer; 26 }?
轉載于:https://www.cnblogs.com/catnip/p/4331347.html
總結
以上是生活随笔為你收集整理的【Weiss】【第03章】练习3.7:有序多项式相乘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对IFeatureClass的选择结果进
- 下一篇: 四则运算的设计思路