数据结构之“Ordered List and Sorted List”(七)

2023-10-25 09:48

本文主要是介绍数据结构之“Ordered List and Sorted List”(七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        本文主要学习“Sorted List”的应用—— 多项式相加(the addition of two polynomials,点击打开链接)。


一、多项式相加的计算机表示

        前面学习“Ordered List”的应用的时候,我们学到用“a sequence of ordered pairs”来表示一个多项式。如下:


        然后,用“Ordered List”来表示这个多项式,并编写了一个算法来求该多项式的微分。(点击打开链接)

        在计算多项式的微分的算法中,多项式中的每一项在序列中的具体位置并不影响该算法的效率。但是,如果我们考虑两个多项式相加的算法:它需要找出指数(exponent)相同的项,即分组(group),然将指数相同的项的系数(coefficient)相加。如果多项式中的项的位置是任意的,这个分组的过程需要多次遍历“Ordered List”,效率非常低。反之,如果多项式的项是从小到大(按指数)排列的,那么这个分组仅需一次遍历。


二、实现

接口声明:

#pragma once
#include "SortedListAsLinkedList.h"// the oredered pair
class TermB : public Object
{
public:TermB(double, unsigned int);void Put(std::ostream &)const;void Differentiate();double Coefficient() const;unsigned int Exponent() const;friend TermB operator+(const TermB&, const TermB&);protected:int CompareTo(Object const &) const;private:double coefficient;unsigned int exponent;
};class SortedPolynomial : public SortedListAsLinkedList
{
public:SortedPolynomial();~SortedPolynomial();SortedPolynomial(SortedPolynomial&);friend SortedPolynomial operator+(const SortedPolynomial &, const SortedPolynomial &);
};

实现

#include "stdafx.h"
#include "SortedPolynomial.h"TermB::TermB(double _coefficient, unsigned int _exponent): coefficient(_coefficient), exponent(_exponent)
{
}void TermB::Put(std::ostream & s) const
{s << typeid(*this).name() << " {";s << coefficient << "," << exponent;s << " }";
}void TermB::Differentiate()
{if (exponent > 0){coefficient *= exponent;--exponent;}elsecoefficient = 0;
}double TermB::Coefficient() const
{return coefficient;
}unsigned int TermB::Exponent() const
{return exponent;
}TermB operator+(const TermB& arg1, const TermB& arg2)
{if (arg1.exponent != arg2.exponent)throw std::domain_error("unequal exponent");return TermB(arg1.coefficient + arg2.coefficient, arg1.exponent);
}int TermB::CompareTo(Object const & object) const
{TermB const & term = dynamic_cast<TermB const &> (object);if (exponent == term.exponent)return ::Compare(coefficient, term.coefficient);elsereturn exponent - term.exponent;
}SortedPolynomial::SortedPolynomial()
{
}SortedPolynomial::~SortedPolynomial()
{
}SortedPolynomial::SortedPolynomial(SortedPolynomial& arg)
{Purge();Pos & pos = *new Pos(arg, arg.linkedList.Head());//Iterator & pos = arg.NewIterator();while (!pos.IsDone()){const TermB & term = dynamic_cast<const TermB &> (*pos);Insert(*new TermB(term));++pos;}
}SortedPolynomial operator+(const SortedPolynomial & arg1, const SortedPolynomial & arg2)
{SortedPolynomial result;ListAsLinkedList::Pos & pos1 = *new ListAsLinkedList::Pos(arg1, arg1.linkedList.Head());ListAsLinkedList::Pos & pos2 = *new ListAsLinkedList::Pos(arg2, arg2.linkedList.Head());//Iterator & pos1 = arg1.NewIterator();//Iterator & pos2 = arg2.NewIterator();while (!pos1.IsDone() && !pos2.IsDone()){const TermB & term1 = dynamic_cast<const TermB &> (*pos1);const TermB & term2 = dynamic_cast<const TermB &> (*pos2);if (term1.Exponent() < term2.Exponent()){result.Insert(*new TermB(term1));++pos1;}else if (term1.Exponent() > term2.Exponent()){result.Insert(*new TermB(term2));++pos2;}else{TermB sum = term1 + term2;if (sum.Coefficient())result.Insert(*new TermB(sum));++pos1;++pos2;}}while (!pos1.IsDone()){const TermB & term1 = dynamic_cast<const TermB &> (*pos1);result.Insert(*new TermB(term1));++pos1;}while (!pos2.IsDone()){const TermB & term2 = dynamic_cast<const TermB &> (*pos2);result.Insert(*new TermB(term2));++pos2;}delete& pos1;delete& pos2;return result;
}


三、测试

测试代码

    // test for Polynomial Addition{SortedPolynomial polynomial;TermB pArray[] = { TermB(5,0), TermB(32,5), TermB(4,2), TermB(56,3), TermB(16,4), TermB(45,1) };for (unsigned int i = 0; i < 6; ++i)polynomial.Insert(pArray[i]);polynomial.Put(std::cout);cout << endl;SortedPolynomial polynomial2;TermB pArray2[] = { TermB(5, 0), TermB(32, 5), TermB(4, 2), TermB(56, 3), TermB(16, 4), TermB(45, 6) };for (unsigned int i = 0; i < 6; ++i)polynomial2.Insert(pArray2[i]);polynomial2.Put(std::cout);cout << endl;SortedPolynomial polynomial3 = polynomial + polynomial2;polynomial3.Put(std::cout);polynomial.RescindOwnership();polynomial2.RescindOwnership();polynomial3.RescindOwnership();}


四、分析和优化

1,“互补多项式”求和

        假设计算两个“互补多项式”(a addition of a polynomial and its arithmetic complement)的和。这两个多项式对应项相加为0,最终结果也为零,即在求和函数中无需执行“Insert”。那么它的总消耗时间就是主循环的次数,即O(n)。

        注:先考虑特殊情况,再考虑一般情况,这是一种解决问题的思路。

2,一般多项求和

        假设两个项数不相等的多项式,p(x) < q(x)。主循环执行L次,次循环执行M次。“Insert”函数为O(k),则求和函数的效率为:



最坏的情况是O(n*n)。主要是因为,我们在分析时假设“Insert”函数不知道每次的具体插入位置。事实上,在循环中,每次都是“在尾部插入”,参照“Insert”函数的实现:

void SortedListAsLinkedList::Insert(Object & object)
{const Node<Object*>* prevPtr = NULL;const Node<Object*>* ptr = linkedList.Head();while (ptr != NULL && *ptr->Datum() < object){prevPtr = ptr;ptr = ptr->Next();}if (!prevPtr)linkedList.Prepend(&object);elselinkedList.InsertAfter(prevPtr, &object);++count;
}

      我们可以进行以下优化,取代Insert。

SortedPolynomial operator+(const SortedPolynomial & arg1, const SortedPolynomial & arg2)
{SortedPolynomial result;ListAsLinkedList::Pos & pos1 = *new ListAsLinkedList::Pos(arg1, arg1.linkedList.Head());ListAsLinkedList::Pos & pos2 = *new ListAsLinkedList::Pos(arg2, arg2.linkedList.Head());//Iterator & pos1 = arg1.NewIterator();//Iterator & pos2 = arg2.NewIterator();while (!pos1.IsDone() && !pos2.IsDone()){const TermB & term1 = dynamic_cast<const TermB &> (*pos1);const TermB & term2 = dynamic_cast<const TermB &> (*pos2);if (term1.Exponent() < term2.Exponent()){result.linkedList.Append(new TermB(term1));// result.Insert(*new TermB(term1));++pos1;}else if (term1.Exponent() > term2.Exponent()){result.linkedList.Append(new TermB(term2)); //result.Insert(*new TermB(term2));++pos2;}else{TermB sum = term1 + term2;if (sum.Coefficient())result.linkedList.Append(new TermB(sum)); // result.Insert(*new TermB(sum));++pos1;++pos2;}}while (!pos1.IsDone()){const TermB & term1 = dynamic_cast<const TermB &> (*pos1);result.linkedList.Append(new TermB(term1)); // result.Insert(*new TermB(term1));++pos1;}while (!pos2.IsDone()){const TermB & term2 = dynamic_cast<const TermB &> (*pos2);result.linkedList.Append(new TermB(term2)); // result.Insert(*new TermB(term2));++pos2;}delete& pos1;delete& pos2;return result;
}

        优化后,运行时间降为O(n)。


这篇关于数据结构之“Ordered List and Sorted List”(七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/281730

相关文章

java streamfilter list 过滤的实现

《javastreamfilterlist过滤的实现》JavaStreamAPI中的filter方法是过滤List集合中元素的一个强大工具,可以轻松地根据自定义条件筛选出符合要求的元素,本文就来... 目录1. 创建一个示例List2. 使用Stream的filter方法进行过滤3. 自定义过滤条件1. 定

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

python中列表list切分的实现

《python中列表list切分的实现》列表是Python中最常用的数据结构之一,经常需要对列表进行切分操作,本文主要介绍了python中列表list切分的实现,文中通过示例代码介绍的非常详细,对大家... 目录一、列表切片的基本用法1.1 基本切片操作1.2 切片的负索引1.3 切片的省略二、列表切分的高

java两个List的交集,并集方式

《java两个List的交集,并集方式》文章主要介绍了Java中两个List的交集和并集的处理方法,推荐使用Apache的CollectionUtils工具类,因为它简单且不会改变原有集合,同时,文章... 目录Java两个List的交集,并集方法一方法二方法三总结java两个List的交集,并集方法一

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

Java中List转Map的几种具体实现方式和特点

《Java中List转Map的几种具体实现方式和特点》:本文主要介绍几种常用的List转Map的方式,包括使用for循环遍历、Java8StreamAPI、ApacheCommonsCollect... 目录前言1、使用for循环遍历:2、Java8 Stream API:3、Apache Commons

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象