【练习3.6】

编写将两个多项式相加的函数。不要毁坏输入数据。用一个链表实现。

如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少?

两个按幂次升序的多项式链表,分别维护一个指针。

幂较小者将元素的副本拷贝入节点并加入新链表,指针向后移动。

幂同样大时,将两者的系数相加后的结果加入新链表,两个多项式链表的指针共同向前移动。

其中一个多项式到达尾部时,如另一个未到达尾部,则一边后移一边将相同元素的新节点加入新链表。

时间复杂度O(M+N)。

测试代码如下:

 #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::polyplus(a, b);
cout << "\n ( " << flush;
answer.traverse();
cout << ") \n" << flush;
system("pause");
}

实现方面,首先定义了多项式类,以及必要的构造函数及运算符重载,放在poly.h头文件中

 #ifndef POLY
#define POLY
#include <iostream>
using namespace std; namespace poly
{
//练习3.6新增,多项式元素定义
class Poly
{
friend bool operator<(const Poly& poly1, const Poly& poly2);
friend bool operator==(const Poly& poly1, const Poly& poly2);
friend bool operator!=(const Poly& poly1, const Poly& poly2);
friend ostream& operator<<(ostream &os, const Poly& poly);
friend Poly operator+(const Poly& poly1, const Poly& poly2);
public:
Poly() = default;
Poly(int coe, int exp) :coefficient(coe), exponent(exp){}
private:
//多项式系数
int coefficient;
//多项式指数
int exponent;
};
//练习3.6新增,多项式元素对应操作符重载,包括<<、<、==、!=,+
bool operator<(const Poly& poly1, const Poly& poly2)
{
return poly1.exponent < poly2.exponent;
}
bool operator==(const Poly& poly1, const Poly& poly2)
{
return poly1.exponent == poly2.exponent;
}
bool operator!=(const Poly& poly1, const Poly& poly2)
{
return !(poly1 == poly2);
}
ostream& operator<<(ostream &os, const Poly& poly)
{
cout << poly.coefficient << "x^" << poly.exponent << flush;
return os;
}
Poly operator+(const Poly& poly1, const Poly& poly2)
{
if (poly1 != poly2)
throw runtime_error("Undefined operation!");
else
{
Poly answer;
answer.coefficient = poly1.coefficient + poly2.coefficient;
answer.exponent = poly1.exponent;
return answer;
}
}
}
#endif

在原链表例程中包含该头文件,并将Poly类与polyplus函数(该函数不是List的成员函数)设为友元

 #ifndef LINKLIST
#define LINKLIST
#include <iostream>
#include "poly.h"      //包含poly头文件
using namespace std;
using namespace poly; namespace linklist
{
/…………/
template <typename T> class List
{
  /…………/
//练习3.6新增,友元声明
friend List<Poly> polyplus(const List<Poly> &inorder_a, const List<Poly> &inorder_b);
friend struct Poly;
/…………/
} /…………/
}

最后是具体实现代码:

 //练习3.6新增,不覆盖原传入数据,多项式相加
List<Poly> polyplus(const List<Poly> &inorder_a, const List<Poly> &inorder_b)
{
List<Poly> answer;
Node<Poly>* pwrite = answer.front;
Node<Poly>* pread_a = inorder_a.front;
Node<Poly>* pread_b = inorder_b.front;
while (pread_a != nullptr && pread_b != nullptr)
{
//为实现升序排列,元素较小者加入新的链表,并向前移动指针
if (pread_a->data < pread_b->data)
{
answer.additem(pread_a->data, pwrite);
if (pwrite == nullptr)
pwrite = answer.front;
else
pwrite = pwrite->next;
pread_a = pread_a->next;
}
else if (pread_b->data < pread_a->data)
{
answer.additem(pread_b->data, pwrite);
if (pwrite == nullptr)
pwrite = answer.front;
else
pwrite = pwrite->next;
pread_b = pread_b->next;
}
//元素一样大时共同向前移动指针
else
{
answer.additem(pread_a->data + pread_b->data, pwrite);
if (pwrite == nullptr)
pwrite = answer.front;
else
pwrite = pwrite->next;
pread_a = pread_a->next;
pread_b = pread_b->next;
}
}
//如果其中任一链表未遍历,将剩余的元素复制入新的链表
while (pread_a != nullptr)
{
answer.additem(pread_a->data, pwrite);
if (pwrite == nullptr)
pwrite = answer.front;
else
pwrite = pwrite->next;
pread_a = pread_a->next;
}
while (pread_b != nullptr)
{
answer.additem(pread_b->data, pwrite);
if (pwrite == nullptr)
pwrite = answer.front;
else
pwrite = pwrite->next;
pread_b = pread_b->next;
}
return answer;
}

【Weiss】【第03章】练习3.6:有序多项式相加的更多相关文章

  1. 第03章 AOP前奏

    第03章 AOP前奏 提出问题 ●情景:数学计算器 ●要求 ①执行加减乘除运算 ②日志:在程序执行期间追踪正在发生的活动 ③验证:希望计算器只能处理正数的运算 ●常规实现 ●问题 ○代码混乱:越来越多 ...

  2. 第03章_基本的SELECT语句

    第03章_基本的SELECT语句 1. SQL概述 1.1 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖 ...

  3. 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 ...

  4. 【Weiss】【第03章】练习3.7:有序多项式相乘

    [练习3.7] 编写一个函数将两个多项式相乘,用一个链表实现.你必须保证输出的多项式按幂次排列,并且任意幂次最多只有一项. a.给出以O(M2N2)时间求解该问题的算法. b.写一个以O(M2N)时间 ...

  5. 【Weiss】【第03章】练习3.8:有序多项式求幂

    [练习3.8] 编写一个程序,输入一个多项式F(X),计算出(F(X))P.你程序的时间复杂度是多少? Answer: (特例:P==0时,返回1.) 如果P是偶数,那么就递归计算((F(X))P/2 ...

  6. 【Weiss】【第03章】练习3.4、3.5:有序链表求交、并

    [练习3.4] 给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∩L2的过程. [练习3.5] 给定两个已排序的表L1和L2,只使用基本的表操作编写计算L1∪L2的过程. 思路比较简单,测 ...

  7. 【Weiss】【第03章】练习3.16:删除相同元素

    [练习3.16] 假设我们有一个基于数组的表A[0,1...N-1],并且我们想删除所有相同的元素. LastPosition初始值为N-1,但应该随着相同元素被删除而变得越来越小. 考虑图3-61中 ...

  8. 【Weiss】【第03章】增补附注

    基本上每章到增补附注这里就算是结束了. 根据设想,每章的这一篇基本上会注明这一章哪些题没有做,原因是什么,如果以后打算做了也会在这里补充. 还有就是最后会把有此前诸多习题的代码和原数据结构放整理后,以 ...

  9. 【Weiss】【第03章】练习3.25:数组模拟队列

    [练习3.25] 编写实现队列的例程,使用 a.链表 b.数组 Answer: 在这章一开头就已经写了个链表的队列例程了,所以实际上只要做b小题就可以. 数组模拟队列和链表的两点小不同是: ①.数组空 ...

随机推荐

  1. CentOS 7上Docker的安装

    一.安装docker 1.Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker . 通过 uname -r 命令查看 ...

  2. 关于安装了Vue-devtools插件但在浏览器控制台不显示的解决方案

    Google浏览器中开发调试的时候,右上角出现vue的图标,但是在开发者工具中没有出现vue调试(已在扩展程序中安装 Vue Devtools) 控制台却没有. 错误原因: 没显示调试工具的原因是用了 ...

  3. 《自动化平台测试开发-Python测试开发实战》新书出版了

    首先 第一本书,当初在百度阅读初步写了个电子版,刚一上线不久即收到了数百位读者朋友阅读收藏购买,于是顺利成章就出版了纸质书. <软件自动化测试开发>认真看过的读者应该都知道,介绍的主要是自 ...

  4. 使用js闭包的好处

    使用闭包有以下几大好处: a:希望一个变量长期驻扎在内存中. b:避免全局变量的污染.

  5. 关于Docker清理

    在Docker的日常使用中,我们或许偶尔遇到下面这些情况: 12345678 $ docker-compose ps[27142] INTERNAL ERROR: cannot create temp ...

  6. Android 代码混淆规则

    1. Proguard介绍 Android SDK自带了混淆工具Proguard.它位于SDK根目录toolsproguard下面.ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器 ...

  7. 微软亚洲研究院开源图数据库GraphView

    我们很高兴地宣布,由微软亚洲研究院系统算法组开发的图数据库GraphView通过GitHub平台开源.GraphView是一款中间件软件,方便用户使用关系数据库SQL Server 或Azure SQ ...

  8. ckeditor 捕获键代码

    <!--<script type="text/javascript"> var ctrlKey = false; var shiftKey = false; if ...

  9. STL迭代器的使用、正向、逆向输出双向链表中的所有元素

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  10. Electron打包H5网页为桌面运行程序

    一.安装配置环境 Electron(一种桌面应用程序运行时),Electron 把 Chromium 和 Node 合并到一个单独的运行时里面,很适合开发桌面 web 形式的应用程序,通过Node它提 ...