【练习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. Android ListView 常用技巧总结

    本文对 ListView 中的一些常用技巧做一个总结.附:虽然现在 RecyclerView 已逐渐取代 ListView,但实际情况是大部分项目中还在使用 ListView.当然,后续我会在我的博客 ...

  2. java的Junit单元测试

    函数主要分为以下几类: 1.有固定返回值的.用assert 方法即可. 2.修改了状态. (1)修改了数据库中的数据.可以查询数据库(select  语句),看数据是否发生了改变. --原则上应该是用 ...

  3. iOS中如何实现准确的倒计时程序 · 九十里

    iOS中倒计时程序,考虑线程暂停场景. iOS App进入后台时,GCD线程也会跟着暂停.当程序进入前台后,GCD线程恢复.因而倒计时程序需要考虑这一点,通过加入时间的比对来实现. + (void)c ...

  4. hexo创建新文章的正确方法

    起因 之前我一直是通过复制以前的文章的形式来创建一个新的文档,但是这一次似乎遇到了一些问题.我将文章写完之后,准备进行预览,输入hexo s命令.在预览页面却没有显示出新的文章,还是和之前的页面是一样 ...

  5. Daily Practice 2016-09-20

    算法 回文(Palindrome)数字:判断一个数字是不是回文数字,不能使用另外的空间. 提示: 负数可以是回文数字吗? 如果转为字符串需要新分配空间 你也许想到了反转数字,但反转数字可能溢出,怎样处 ...

  6. ElasticSearch系列四 CURD

    1: ES 类似JPA操作 1.1 编写实体类 1.2 编写映射文件 xxx.json 1.3编写repository继承 ElasticSearchrepository 1.4 编写admin 的C ...

  7. C++走向远洋——25(项目二,游戏类)

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

  8. [ASP.NET Core 3框架揭秘] 服务承载系统[1]: 承载长时间运行的服务[上篇]

    借助.NET Core提供的承载(Hosting)系统,我们可以将任意一个或者多个长时间运行(Long-Running)的服务寄宿或者承载于托管进程中.ASP.NET Core应用仅仅是该承载系统的一 ...

  9. 小白学 Python 数据分析(12):Pandas (十一)数据透视表(pivot_table)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  10. 微服务架构-Gradle下载安装配置教程

    一.开发条件 JDK8下载地址:https://www.oracle.com/java/technologies/javase-jdk8-downloads.html Eclipse下载地址:http ...