【练习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:有序多项式相乘的更多相关文章

  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.8:有序多项式求幂

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

  5. 【Weiss】【第03章】练习3.6:有序多项式相加

    [练习3.6] 编写将两个多项式相加的函数.不要毁坏输入数据.用一个链表实现. 如果这两个多项式分别有M项和N项,那么你程序的时间复杂度是多少? 两个按幂次升序的多项式链表,分别维护一个指针. 幂较小 ...

  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. RxJava操作符实践:8_算术和聚合操作之3_min

    发射原始Observable的最小值. Min操作符操作一个发射数值的Observable并发射单个值:最小的那个值. RxJava中,min属于rxjava-math模块. min接受一个可选参数, ...

  2. php 依赖注入 和 控制反转 php设计模式

    https://blog.csdn.net/zyddj123/article/details/82753650 什么是依赖注入?IOC:英文全称:Inversion of Control,中文名称:控 ...

  3. 最简化的DirectX 11开发环境的配置 VS2010

    转载自:http://blog.csdn.net/zhmxy555/article/details/7672101 在编写基于DirectX 11的应用程序之前,我们当然需要在IDE中加入Direct ...

  4. unittest(2)-加载用例的3种方式-输出测试报告

    # 导入测试类执行测试用例 import unittest from day_20191202.class_unittest import TestMathMethod, TestMulti # fr ...

  5. 吴裕雄--天生自然 R语言开发学习:基本图形

    #---------------------------------------------------------------# # R in Action (2nd ed): Chapter 6 ...

  6. Python Web 基础向(四) 浅谈数据层

    数据层一般会给人带来一些困扰,在于其定位不准确.聚合Model的工作也可以放在逻辑层做,但会导致逻辑层变重,经常出现大段晦涩代码.因此我的建议是保留Model聚合层,尽管会导致工作量的略微增加,但却可 ...

  7. Ionic3学习笔记(九)关于 Android 端软键盘弹出后界面被压缩的问题

    本文为原创文章,转载请标明出处 今天做了一个如下图所示的页面. iOS 端毫无 bug,Android 端却出现了问题.当软键盘弹出后,Android 端的 tabs 移到了软键盘的上面,再仔细一看, ...

  8. The Process class relies on proc_open, which is not available on your PHP installation报错解决

    同事laravel框架开发的代码有如下错误日志 production.ERROR: The Process class relies on proc_open, which is not availa ...

  9. IDEA 详细使用教程

    第一步:安装 略 安装首先需要Java语言的运行环境,这里不做概述. 第二步:破解 这里使用的是2016版的,所以直接在网上搜索秘钥即可 https://blog.csdn.net/ksksjipen ...

  10. 从假图片到假新闻,AI就这样“控制”了我们

    在评论某位新蹿红的明星时,围观群众总是习惯性地先从长相上来判定,如"像周润发和梁朝伟的合体"."刘德华和郭富城的合体"等--反正比"黄渤和王宝强的合体 ...