【练习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:有序多项式相乘相关推荐

  1. 2.c语言编译预处理,c语言第03章-编译预处理2.ppt

    c语言第03章-编译预处理2 第3章 编译预处理 编译预处理是指,编译时,首先对编译预处理命令进行处理,然后再将预处理后的中间结果进行编译,以得到目标代码. 教学目的: 掌握#define.#incl ...

  2. 《微机原理及接口技术》第03章在线测试

    <微机原理及接口技术>第03章在线测试  <微机原理及接口技术>第03章在线测试 剩余时间: 59:53  答题须知:1.本卷满分20分.            2.答完题后, ...

  3. c语言单字符输入和输出函数分别为,第03章单元总练习-实训-知识拓展.doc

    第03章单元总练习-实训-知识拓展 <C语言程序设计> 单元总结单元练习 实训指导知识拓展 第三章 最简单的C程序设计 --顺序结构设计 班级: 姓名: 学号: 单元总结提升 本单元中,核 ...

  4. 计算机专业英语第三章在线测试,《计算机专业英语》第03章在线测试

    <计算机专业英语>第03章在线测试 剩余时间: 57:06 答题须知:1.本卷满分20分. 2.答完题后,请一定要单击下面的"交卷"按钮交卷,否则无法记录本试卷的成绩. ...

  5. 《C Prime Plus》(第六版) 第03章 编程练习 7 英寸转换成厘米

    C Prime Plus 第六版 编译器版本:Mac Xcode 11.6  第03章 数据和C 编程练习 7 7. 1英寸相当于2.54厘米.编写一个程序,提示用户输入身高(/英寸),然后以厘米为单 ...

  6. 利用自动机识别c 语言单词,第03章 词法分析与有穷自动机(2).ppt

    <第03章 词法分析与有穷自动机(2).ppt>由会员分享,可在线阅读,更多相关<第03章 词法分析与有穷自动机(2).ppt(59页珍藏版)>请在人人文库网上搜索. 1.3. ...

  7. 《C Prime Plus》(第六版) 第03章 编程练习 8 品脱/盎司/大汤勺/茶勺单位换算

    C Prime Plus 第六版 编译器版本:Mac Xcode 11.6  第03章 数据和C 编程练习 8 在美国的体积测量系统中,1品脱等于2杯,1杯等于8盎司,1盎司等于2大汤勺,1大汤勺等于 ...

  8. 《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第03章 加工原料文本

    第03章 加工原料文本 3.1 从网络和硬盘访问文本 电子书 处理的HTML 处理搜索引擎的结果 处理RSS 订阅 读取本地文件 从PDF.MS Word 及其他二进制格式中提取文本 捕获用户输入 N ...

  9. 青少年成长管理 第03章 成长目标

    "不管多么辉煌的成果,都只能开始于宏伟的蓝图" 成长目标就是成长主体最终想成为什么样的人. 人类活在故事里,你要先构造一个传奇的故事,然后开始你的表演.故事还没有编好?那你怎么演啊 ...

最新文章

  1. 读书笔记_java设计模式深入研究 第八章 状态模式 State
  2. Python中Numpy包的学习
  3. 赛锐信息:SAP ABAP 屏幕导航
  4. Jquery 学习心得和资料
  5. 在Idea中连接数据库并生成实体类(mybatis逆向生成实体类)
  6. 工具-管理工具资源集合
  7. mongo的‘模糊匹配’
  8. Java面试题之分布式事务篇
  9. Uploadify-中文帮助手册
  10. Java菜鸟的初次实习经历
  11. 【连载之一】那些公众号不会告诉你的职业真相
  12. 小鑫的算法之路:leetcode0704 二分查找
  13. [转]治近视的秘方!1000度近视降到只有200度
  14. C语言中三个数比较大小详解——三种方法
  15. 钉钉中添加回调监听事件
  16. 云管平台 | 云成本分析优化管理
  17. Java虚拟机这一块 —— 深入理解java虚拟机(jvm)
  18. 那些年啊,那些事——一个程序员的奋斗史 ——127
  19. 100首经典好听的外文歌曲!
  20. Aspect @Pointcut切入点解释

热门文章

  1. 【☀️不定期更新了⛅】感谢知识输出的正反馈
  2. PyTorch基础(八)----- torch.split()方法
  3. STM32开发 -- WIFI那些事儿(一)
  4. PAT——程序运行时间 (1026)
  5. 对深度学习的逃逸攻击 — 探究人工智能系统中的安全盲区
  6. JAndFix: 基于Java实现的Android实时热修复方案
  7. Android动态加载技术三个关键问题详解
  8. 应用层的AIDL用法(原)
  9. 你应该知道的那些Android小经验
  10. 基于本地部署的hyperledger fabric升级chaincode