一元多项式的表示及相加
设计目的与要求
题目与设计要求
我们设计的程序为一元多项式的表示及相加,这是使用C++语言写成。我们使用计算机处理的对象之间通常存在着的是一种最简单的线性关系,这类数学模型可称为线性的数据结构。而数据存储结构有两种:顺序存储结构和链式存储结构。线性表是最常用且最简单的一种数据结构。所以我们做的是———–一元多项式的表示及相加,其过程其实是对线性标的操作。实验结构和链接存储结构上的运算以及熟练运用掌握的线性表的操作,实现一元n次多项式的目的是掌握线性表的基本操作,插入、删除、查找,以及线性表合并等运算在顺序存储的加法运算。学习实现一元n次多项式的加法是符号多项式的操作,是表处理的典型用例,需要注意的是:顺序存储结构指的是用数组方法,使用数组方法实现时,在插入和删除的方面,数组不如链表灵活,方法复杂,删除其中一个需要将其后的数组元素改变位置,使其数组保持原有的顺序结构,在查找方面较链表简单,只需要知道其下标就可以知道。链接存储结构指的是用链表方法,值得注意的是,删除和插入较为灵活,不需要变动大多数元素,但是查找过程相对于数组这种顺序存储结构来说较为复杂,耗时巨大。在这里我们在一元多项式的表示与相加实验中,采用的是链式存储结构。
我们程序的任务是: 实现一元多项式:Rn(x)=Pn(x)+Qn(x)
本程序涉及的知识点
1 | If语句 switch语句 for循坏 do…while循坏 指针 结构体 函数的套用 线性表的操作 线性表链式存储结构 对内存空间的开辟与释放 |
功能设计
总体设计
我们需要实现的功能是一元多项式的表示及相加。但在实现一元多项式的过程中,主要是通过对链表的操作来完成的。所以,这里还实现的对链式线性表的基本操作。例如,插入、删除、查找等。对于一元多项式,需要实现一元多项式的创建,同时可以打印出一元多项式,可以对两个多项式进行加法运算。
详细设计
(1)项目工程文件规划:
在这个项目中,我设计使用三个头文件,和一个cpp源文件。以下为各个文件的主要作用:
- Base.h:
这个头文件中主要用来存放一些项目需要的头文件和公用的常量和类型。并且一元多项式的存储结构也放在这里。
- LinkList.h:
这个头文件为链表头文件,其中主要包含了链式线性表的存储结构和链式线性表的各函数具体实现代码。在这个头文件中实现的方法有:InitList(); MakeNode(); FreeNode();InsFirst(); GetHead(); SetCurElem(); LocateElemP(); NextPos(); GetCurElem(); DelFirst();ListEmpty(); Append(); ListTraverse();
- Polynomial.h:
这个头文件是一元多项式头文件,其中主要包含了一元多项式的基本操作的各种方法的实现代码。在这个头文件中实现的方法有:CreatPolyn(); DestroyPolyn(); PolynLength(); PrintPolyn(); AddPolyn();
- Main.cpp:
这是一个cpp源文件,也是程序测试文件。它的功能主要是对一元多项式方法的测试,检测所需功能是否完成。
(2)程序存储结构的设计:
链表存储结构:
1 | //----------链表的存储结构表示------------ |
一元多项式存储结构:
1 | //---------------一元多项式存储结构表示----------- |
一元多项式其实就是通过链式线性表来存放。通过对线性表的操作进而实现对一元多项式的操作。
程序主要方法的实现
创建多项式的实现:
这是一元多项式程序中主要一个方法,通过它来创建一元多项式。在这个函数中首先会要求传入需要创建几项多项式。然后会通过循环输入每项的系数和指数来生成多项式。其实也就是生成一个按指数升序的链表,以方便后面做一元多项式的加法运算。
在创建一元多项式中,考虑到了用户输入数据的多种情况:每种情况都做了相应的输入策略,每次在插入一个数据项时,首先都会查找是否存在该指数项。如果不存在,然后判断系数是否为0.如果为0,不添加,进行下一次循环。如果不为0,则正常添加一个节点。这个结点是在升序链表中找到适合的位置进入插入,而不是随便添加结点。如果在添加查找该指数时,发现该指数项已经存在,则在原来该指数项的系数上添加上该系数。如果添加后系数等于0.则删除该结点。不为0,则正常进入下一次循环,添加其他数据项。
以下为此函数具体实现代码:
1 | void CreatPolyn(polynomial &p,int m){ |
一元多项式相加的具体实现:
在一元多项式相加的函数中。首先会要求传入两个已经创建好的一元多项式PA,PB,然后进行相加,实现PA=PA+PB的功能。
程序执行过程:只有在Pa和Pb都不为空的时候程序才会进行循环,因为一元多项式以链式线性表以指数升序存储。所以每次进入循环都会首先比较Pa和Pb中的需要比较的qa和qb中指数的大小。如果qa的指数小,则会ha和qa指针都后移,继续比较。如果qa和qb的指数相等,则会把qa和qb的系数进行相加并赋值给qa的系数。从而实现相同指数的系数相加,加完后将qb所指结点删除,同时qa后qb指针都后移。如果qa的指数比qb大,则把qb所在的结点链接到qa的前面。qb指针继续后移。进行循环。这是就这个加法的具体实现过程。在最后,如果qa已经为空,而qb不为空,则把qb剩下的结点都直接链接在PA的最后。释放hb的头结点。
1 | void AddPolyn(polynomial &Pa, polynomial &Pb){ |
打印多项式的具体实现:
在这个函数,主要调用了ListTraverse(),即对链表进行遍历。通过循环,输出每个结点的数据。循环的次数为一元多项式这个链表的项数。每次输出数据时,调用visit(()函数,在visit函数中,我对输入的各种可能系数和指数进行了情况输出。如果系数为1,则不输出系数。如果系数和指数为负数,则会输出括号,在括号内输出负数。如果指数为1,则不输出指数。如果指数为0,则该项为常数,只输出系数。
1 | void PrintPolyn(polynomialp){ |
程序测试结果
这里对程序使用了三组数据进行测试:
第一组测试:
第一组测试数据为指数和系数都是正整数的情况。例:PA=3+4x+3x^2 +4x^4; PB=4+6x^2 +3x^4 +3x^5;求PA=PA+PB。如下图4.1:
第二组测试:
第二组测试数据为指系数和指数中都有负数的情况。有负数时,会在负数上加上括号来显示。例:PA=-5x^(-2) +4-3x^2 +4x^3; PB=3x^(-3) +3x^2 -4x^3; 求PA=PA+PB;测试结果如下图4.2:
第三组测试:
第三组测试数据为:系数中存在0的情况,和指数中存在1的情况。系数中存在0,在程序执行过程中会自动删除该项。指数为1的时候,该多项式不会显示指数项。例:PA=4+0x^3 +4x^4 -3x^5; PB=3+x^1 +3x^3 +4x^5; 求PA=PA+PB;测试结果如下图4.3:
总结:
在做这个程序过程中,我遇到过很多问题,比如有时候调试可以通过,然而程序却不能正确执行,总会出错。这种情况只能去仔细检查对应代码的逻辑是否有错误。把可能出现的情况去修改,然后慢慢去调试。通过这样的反复调试,我感觉对线性链表的知识理解更加深刻。同时,对写代码也有了很多练习,写的代码更规范,更简洁。在这个实验过程中,也与我的小组队员进行了多次讨论,让我们懂得了团队合作的重要性。通过小组讨论,使我对一些模糊不清的地方了解透彻,同时小组其他成员也都理解了相应的知识。最后,通过这个实验,使我对链式线性表可以很熟练的去运用。同时,对一元多项式的简单操作也有了清晰的认识。只有经常进行编程练习,我们的编程能力才能得到有效提高。
全部代码:
base.h
1 | //base.h |
LinkList.h
1 | //LinkList.h |
Polynomial.h
1 | //Polynomial.h |
Main.cpp
1 |
|