【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(M²N)时间执行多项式乘法 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:有序多项式相乘相关推荐
- 2.c语言编译预处理,c语言第03章-编译预处理2.ppt
c语言第03章-编译预处理2 第3章 编译预处理 编译预处理是指,编译时,首先对编译预处理命令进行处理,然后再将预处理后的中间结果进行编译,以得到目标代码. 教学目的: 掌握#define.#incl ...
- 《微机原理及接口技术》第03章在线测试
<微机原理及接口技术>第03章在线测试 <微机原理及接口技术>第03章在线测试 剩余时间: 59:53 答题须知:1.本卷满分20分. 2.答完题后, ...
- c语言单字符输入和输出函数分别为,第03章单元总练习-实训-知识拓展.doc
第03章单元总练习-实训-知识拓展 <C语言程序设计> 单元总结单元练习 实训指导知识拓展 第三章 最简单的C程序设计 --顺序结构设计 班级: 姓名: 学号: 单元总结提升 本单元中,核 ...
- 计算机专业英语第三章在线测试,《计算机专业英语》第03章在线测试
<计算机专业英语>第03章在线测试 剩余时间: 57:06 答题须知:1.本卷满分20分. 2.答完题后,请一定要单击下面的"交卷"按钮交卷,否则无法记录本试卷的成绩. ...
- 《C Prime Plus》(第六版) 第03章 编程练习 7 英寸转换成厘米
C Prime Plus 第六版 编译器版本:Mac Xcode 11.6 第03章 数据和C 编程练习 7 7. 1英寸相当于2.54厘米.编写一个程序,提示用户输入身高(/英寸),然后以厘米为单 ...
- 利用自动机识别c 语言单词,第03章 词法分析与有穷自动机(2).ppt
<第03章 词法分析与有穷自动机(2).ppt>由会员分享,可在线阅读,更多相关<第03章 词法分析与有穷自动机(2).ppt(59页珍藏版)>请在人人文库网上搜索. 1.3. ...
- 《C Prime Plus》(第六版) 第03章 编程练习 8 品脱/盎司/大汤勺/茶勺单位换算
C Prime Plus 第六版 编译器版本:Mac Xcode 11.6 第03章 数据和C 编程练习 8 在美国的体积测量系统中,1品脱等于2杯,1杯等于8盎司,1盎司等于2大汤勺,1大汤勺等于 ...
- 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第03章 加工原料文本
第03章 加工原料文本 3.1 从网络和硬盘访问文本 电子书 处理的HTML 处理搜索引擎的结果 处理RSS 订阅 读取本地文件 从PDF.MS Word 及其他二进制格式中提取文本 捕获用户输入 N ...
- 青少年成长管理 第03章 成长目标
"不管多么辉煌的成果,都只能开始于宏伟的蓝图" 成长目标就是成长主体最终想成为什么样的人. 人类活在故事里,你要先构造一个传奇的故事,然后开始你的表演.故事还没有编好?那你怎么演啊 ...
最新文章
- 读书笔记_java设计模式深入研究 第八章 状态模式 State
- Python中Numpy包的学习
- 赛锐信息:SAP ABAP 屏幕导航
- Jquery 学习心得和资料
- 在Idea中连接数据库并生成实体类(mybatis逆向生成实体类)
- 工具-管理工具资源集合
- mongo的‘模糊匹配’
- Java面试题之分布式事务篇
- Uploadify-中文帮助手册
- Java菜鸟的初次实习经历
- 【连载之一】那些公众号不会告诉你的职业真相
- 小鑫的算法之路:leetcode0704 二分查找
- [转]治近视的秘方!1000度近视降到只有200度
- C语言中三个数比较大小详解——三种方法
- 钉钉中添加回调监听事件
- 云管平台 | 云成本分析优化管理
- Java虚拟机这一块 —— 深入理解java虚拟机(jvm)
- 那些年啊,那些事——一个程序员的奋斗史 ——127
- 100首经典好听的外文歌曲!
- Aspect @Pointcut切入点解释