【练习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. [LC] 17. Letter Combinations of a Phone Number

    Given a string containing digits from 2-9 inclusive, return all possible letter combinations that th ...

  2. Java程序、JSP以及JavaScript中如何判断某个字符串是否包含某个子串

    1.JSP str:原始字符串, subStr:要查找的子字符串 <c:if test="${fn:contains(str,subStr)==true}"> < ...

  3. Ionic3学习笔记(十三)HttpClient 实现 HTTP 请求以及踩过的一些坑

    本文为原创文章,转载请标明出处 目录 猫眼API HttpClient 实现 HTTP 请求 安装 HttpClientModule 模块 创建 provider 创建 page 一些坑 坑1: 未在 ...

  4. unittest(9)- 使用ddt给测试用例传参

    # 1. http_request.py import requests class HttpRequest: def http_request(self, url, method, data=Non ...

  5. 为啥java要使用 set ()和get()方法---封装

    封装性:属性封装,方法封装,类封装,组件封装等 例如:如果属性没有封装,那么在本类对象之外创建对象后,可以直接访问属性 private关键字,只能在本类中访问,想要在外部访问私有属性,我们需要提供公有 ...

  6. 用手机应用追踪城市噪声污染——微软Azure助力解决城市问题

    噪声无孔不入的城市地带(图片来自于网络) 2014年4月19日发行的<经济学人>杂志预言,到2030年,中国人口的70%(约10亿人)会在城市中居住.中国城镇化的高速发展一方面大大提高了 ...

  7. Ubuntu 14.10 进入单用户模式

    1. 开机,进入grub界面 2. 此时会有一个选项:Advanced Options for Ubuntu(ubuntu高级), 选中直接回车 3. 看到里面有很多选项,选中后面带recovery ...

  8. Vue Zero · 啟

    其实,一开始我应聘的是Spark,Hadoop这样的,然后后面呢,发现只有Java的业务给我写了,再后面我发现,公司招不到前端,所以前端要由后端来写,刺激!!! 数据驱动 首先要明白一个概念,那就是D ...

  9. oa办公系统快速开发工具,助力企业优化升级

    随着互联网的快速发展.信息化 IT 技术的不断进步.移动互联新技术的兴起,不管是大的集团企业还是中小型企业,纸质化的办公模式已不能满足现有需求,构建oa平台,为员工提供高效的办公环境尤其重要. 我们先 ...

  10. Yuchuan_Linux_C编程之一 Vim编辑器的使用

    一.整体大纲 二.Vim 编辑器的使用 vi -- vim    vim是从vi发展过来的一款文本编辑器    vi a.txt    前提: 安装了vim软件 工作模式: 1. 命令模式 -- 打开 ...