【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的测试代码写在一起了
#include <iostream>
#include "linklist.h"
using linklist::List;
using namespace std;
int main(void)
{
//测试多项式加法
List<Poly> a;
a.additem(Poly(, ));
a.additem(Poly(, ));
a.additem(Poly(, ));
a.additem(Poly(, ));
a.additem(Poly(, ));
cout << " ( " << flush;
a.traverse();
cout << ") +\n" << flush;
List<Poly> b;
b.additem(Poly(, ));
b.additem(Poly(, ));
b.additem(Poly(, ));
b.additem(Poly(, ));
b.additem(Poly(, ));
cout << " ( " << flush;
b.traverse();
cout << ") =\n" << flush; List<Poly> answer = linklist::polymulti_seq(a, b);
List<Poly> another = linklist::polymulti_sort(a, b);
cout << "\n ( " << flush;
answer.traverse();
cout << ") \n" << flush; cout << "\n ( " << flush;
another.traverse();
cout << ") \n" << flush;
system("pause");
}
实现部分,首先需在poly.h中重载多项式元素的乘法运算符
//练习3.7新增,多项式元素乘法*
Poly operator*(const Poly& poly1, const Poly& poly2)
{
Poly answer;
answer.coefficient = poly1.coefficient*poly2.coefficient;
answer.exponent = poly1.exponent + poly2.exponent;
return answer;
}
然后是小题b代码,包括习题3.5求并成员函数的模板特例化的辅助函数及主相乘算法
//练习3.7b新增,将3.5求并的成员函数特例化
template <> void List<Poly>::join(List<Poly> inorder)
{
Node<Poly>* curr = front;
Node<Poly>* prev = nullptr;
Node<Poly>* curr2 = inorder.front;
while (curr != nullptr && curr2 != nullptr)
{
if (curr->data < curr2->data)
{
prev = curr;
curr = curr->next;
}
else if (curr2->data < curr->data)
{
additem(curr2->data, prev);
if (prev == nullptr)
prev = front;
else
prev = prev->next;
curr2 = curr2->next;
}
else
{
//对比3.5唯一增加语句
//当两元素幂次相等时,原链表与新链表的多项式系数相加并将指针后移
curr->data = curr->data + curr2->data;
prev = curr;
curr = curr->next;
curr2 = curr2->next;
}
}
while (curr2 != nullptr)
{
additem(curr2->data, prev);
if (prev == nullptr)
prev = front;
else
prev = prev->next;
curr2 = curr2->next;
}
} //练习3.7b新增,以O(M²N)时间执行多项式乘法
List<Poly> polymulti_seq(const List<Poly> &inorder_a, const List<Poly> &inorder_b)
{
//保证首链表长度较小
if (inorder_a.size() > inorder_b.size())
return polymulti_seq(inorder_b, inorder_a);
else
{
List<Poly> answer;
for (Node<Poly>* iter_a = inorder_a.begin(); iter_a != nullptr; iter_a = iter_a->next)
{
//用较短链表中每一个元素乘较长链表,得到临时链表
{
List<Poly> temp;
for (Node<Poly>* iter_b = inorder_b.begin(); iter_b != nullptr; iter_b = iter_b->next)
temp.additem(iter_a->data * iter_b->data);
answer.join(temp);
}
}
return answer;
}
}
然后为c小题算法,调用了标准库中的快排,需要#include<algorithm>
//练习3.7c新增,以O(MNlogMN)时间执行多项式乘法
List<Poly> polymulti_sort(const List<Poly> &inorder_a, const List<Poly> &inorder_b)
{
unsigned maxsize = inorder_a.size() * inorder_b.size();
//申请M*N大小的数组
Poly* temp_array = new Poly[maxsize];
unsigned int index = ;
//依次对链表每两个节点元素相乘并放在数组中
for (Node<Poly>* iter_a = inorder_a.begin(); iter_a != nullptr; iter_a = iter_a->next)
for (Node<Poly>* iter_b = inorder_b.begin(); iter_b != nullptr; iter_b = iter_b->next)
temp_array[index++] = iter_a->data*iter_b->data;
//对数组进行升序快排
sort(&temp_array[], &temp_array[--index]);
List<Poly> answer;
//单次遍历数组,合并同类项
for (index = ; index < maxsize; ++index)
{
if (temp_array[index] == temp_array[index - ])
temp_array[index] = temp_array[index - ] + temp_array[index];
else
answer.additem(temp_array[index - ]);
}
answer.additem(temp_array[index - ]);
delete[] temp_array;
return answer;
}
【Weiss】【第03章】练习3.7:有序多项式相乘的更多相关文章
- 第03章 AOP前奏
第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...
- 第03章_基本的SELECT语句
第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第03章 - 部署flannel插件
文章目录 1.3.部署flannel网络 1.3.0.下载flannel二进制文件 1.3.1.创建flannel证书和私钥 1.3.2.生成flannel证书和私钥 1.3.3.将pod网段写入et ...
- 【Weiss】【第03章】练习3.8:有序多项式求幂
[练习3.8] 编写一个程序,输入一个多项式F(X),计算出(F(X))P.你程序的时间复杂度是多少? Answer: (特例:P==0时,返回1.) 如果P是偶数,那么就递归计算((F(X))P/2 ...
- 【Weiss】【第03章】练习3.6:有序多项式相加
[练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...
- 【Weiss】【第03章】练习3.4、3.5:有序链表求交、并
[练习3.4] 给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∩L2的过程. [练习3.5] 给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∪L2的过程. 思路比较简单,测 ...
- 【Weiss】【第03章】练习3.16:删除相同元素
[练习3.16] 假设我们有一个基于数组的表A[0,1...N-1],并且我们想删除所有相同的元素. LastPosition初始值为N-1,但应该随着相同元素被删除而变得越来越小. 考虑图3-61中 ...
- 【Weiss】【第03章】增补附注
基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...
- 【Weiss】【第03章】练习3.25:数组模拟队列
[练习3.25] 编写实现队列的例程,使用 a.链表 b.数组 Answer: 在这章一开头就已经写了个链表的队列例程了,所以实际上只要做b小题就可以. 数组模拟队列和链表的两点小不同是: ①.数组空 ...
随机推荐
- top100 paper
- 吴裕雄--python学习笔记:sqlite3 模块
1 sqlite3.connect(database [,timeout ,other optional arguments]) 该 API 打开一个到 SQLite 数据库文件 database 的 ...
- eclipse、myeclipse使用常用的小技巧
1.修改类名称上的@author *** Preference----Java----Code Style----Code Templates----->Comments----->Ty ...
- 在MySql中如何定义像Java中类型的Boolean类型
在MySql中如何定义像Java中类型的Boolean类型数据..其实,mysql中 是没有直接定义成Boolean这种数据类型.它只能定义成 tinyint(1) ;如果长度是1,tinyint(1 ...
- loadrunner通过odbc测mysql数据库语句
#include "lrd.h" Action() { double trans_time; //定义一个double型变量用来保存事务执行时间 static LRD_INIT_ ...
- docker运行mysql主从备份,读写分离
1)从Docker官方下拉MySQL的image 打开https://hub.docker.com/ 搜索mysql 在docker中运行 默认tag为latest docker pull mysql ...
- iOS多线程开发之NSOperation
一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...
- RocketMQ介绍与实践
一.RocketMQ介绍 1.相关术语名词 1. NameSrv:是一个几乎无状态节点,可集群部署,节点之间无任何信息同步. 2. Broker:分为Master与Slave,一个 ...
- SecureCRT语法高亮设置
因为默认情况下,SecureCRT不能显示语法高亮特性,整个界面颜色单一,看起来不爽,也没有效率,所有通过设置一下语法高亮还是很有必要的, 默认字体也看着不是很清晰,还是更改为我比较喜欢的Courie ...
- AI:是猫还是狗,这是个问题
如果你不喜欢小猫和小狗,你可能不知道他们具体是哪一种品种,但是一般来说,你都能区分出这是猫还是狗,猫和狗的特征还是不一样的,那我们如何用机器学习的方法训练一个网络区分猫狗呢? 我们选用的是 Kaggl ...