CPolynomial.h文件
#pragma once
/*
*Copyright© 中国地质大学(武汉) 信息工程学院
*All right reserved.
*
*文件名称:CPolynomial.h
*摘 要:利用链表结构完成多项式的表示及其运算
*
*当前版本:1.0
*作 者:邵玉胜
*完成日期:2018-04-16
*/
//多项式的类定义
#ifndef POLYNOMIAL_H_
#define POLYNOMIAL_H_
#include<iostream>
using namespace std;
struct Term //多项式节点的定义
{
float m_dCoef; //系数
int m_nExp; //指数
Term* m_pLink;
Term(float c, int e, Term *next = nullptr)
{
m_dCoef = c;
m_nExp = e;
m_pLink = next;
}
Term* InsertAfter(float c, int e);
friend ostream& operator<<(ostream&, const Term&);
};
class CPolynomial //多项式类定义
{
public:
CPolynomial() { m_pFirst = new Term(0, -1); } //构造函数,构造空链表
~CPolynomial(); //析构函数
CPolynomial(CPolynomial& R); //复制构造函数
CPolynomial& operator = (CPolynomial& R); //重载赋值运算符
int maxOrder(); //计算最大阶数
Term* getHead()const { return m_pFirst; } //取得多项式单链表的表头指针
private:
Term* m_pFirst;
friend ostream& operator <<(ostream&, const CPolynomial&);
friend istream& operator >>(istream&, CPolynomial&);
friend CPolynomial operator + (CPolynomial&, CPolynomial&);
friend CPolynomial operator *(CPolynomial&, CPolynomial&);
};
#endif
CPolynomial.cpp文件
#include"Polynomial.h"
Term* Term::InsertAfter(float c, int e)
{
//在当前由this指针指示的项(即调用此函数的对象)后面插入一个新项
m_pLink = new Term(c, e);
return m_pLink;
}
ostream& operator<<(ostream& out, const Term& term)
{
//Term的友元函数,输出一个项x的内容到输出流out中
if (term.m_dCoef == 0) return out; //零系数项,不输出
out << term.m_dCoef;
switch (term.m_nExp)
{
case 0:
break;
case 1:
out << "X";
break;
default:
out << "X^" << term.m_nExp;
break;
}
return out;
}
CPolynomial::CPolynomial(CPolynomial& P)
{
//复制构造函数,用已有多项式对象R初始化当前多项式对象
m_pFirst = new Term(0, -1);
Term* destPtr = m_pFirst;
Term* srcPtr = P.getHead()->m_pLink;
while (srcPtr != nullptr)
{
destPtr->InsertAfter(srcPtr->m_dCoef, srcPtr->m_nExp);
//在destptr所指定节点后插入新节点,再让destptr指到这个新节点
srcPtr = srcPtr->m_pLink;
destPtr = destPtr->m_pLink;
}
}
CPolynomial& CPolynomial::operator = (CPolynomial& P) {
//m_pFirst = new Term(0, -1);
Term* destPtr = m_pFirst;
Term* srcPtr = P.getHead()->m_pLink;
while (srcPtr != nullptr)
{
destPtr->InsertAfter(srcPtr->m_dCoef, srcPtr->m_nExp);
//在destptr所指定节点后插入新节点,再让destptr指到这个新节点
srcPtr = srcPtr->m_pLink;
destPtr = destPtr->m_pLink;
}
return *this;
}
CPolynomial::~CPolynomial() { //析构函数
Term* destPtr = m_pFirst;
while (destPtr != nullptr) {
m_pFirst = m_pFirst->m_pLink;
delete destPtr;
destPtr = m_pFirst;
}
}
int CPolynomial::maxOrder()
{
//计算最大阶数,当多项式按升序排序时,最后一项中时最大指数者
Term* current = m_pFirst;
while (current->m_pLink != nullptr)
current = current->m_pLink;
//空表情形,current停留在m_pFirst,否则current停留在表尾节点
return current->m_nExp;
}
istream& operator>>(istream& in, CPolynomial& P)
{
//CPolynomia类的友元函数,从输入流in输入各项,用尾插法建立一个多项式
Term* rear = P.getHead();
cout << "输入一个二项式,以0 -1结束" << endl;
float coef;
int exp;
while(in >> coef >> exp){
if (exp < 0.0) //如果指数小于0,就结束循环
break;
rear = rear->InsertAfter(coef, exp); //插入
//rear = rear->m_pLink;
}
return in;
}
ostream& operator <<(ostream& out, const CPolynomial& P)
{
//CPolynomial类的友元函数:输出带附加头结点的多项式链表x
Term* srcPtr = P.getHead()->m_pLink;
float coef = 0.0;
int exp = 0;
int count = 1;
while (srcPtr != nullptr) {
coef = srcPtr->m_dCoef;
exp = srcPtr->m_nExp;
if (exp == 0)
out << coef;
else if (coef < 0.0)
out << coef << "X^" << exp;
else if(coef > 0 && count == 1)
out << coef << "X^" << exp;
else
out << "+" << coef << "X^" << exp;
srcPtr = srcPtr->m_pLink;
count++;
}
out << endl;
return out;
}
//两个多项式的相加运算
CPolynomial operator + (CPolynomial& A, CPolynomial& B)
{
//友元函数:两个带附加头结点的按升幂排序的多项式链表的头指针分别是A.m_pFirst与B.m_pFirst
//返回的是结果多项式的链表
CPolynomial result; //用于返回的对象
Term* pResult = result.getHead();
Term* pA = A.getHead()->m_pLink; //指向参数多项式A的第一项的指针
Term* pB = B.getHead()->m_pLink; //指向参数多项式B的第一项的指针
float dAddCoef = 0.0;
Term* pLast = nullptr; //用于指向剩下的多项式的第一项
while (pA != nullptr && pB != nullptr) { //如果两个有一个没有达到最后一项,就一直循环
if (pA->m_nExp == pB->m_nExp) {
dAddCoef = pA->m_dCoef + pB->m_dCoef;
if (abs(dAddCoef) > 0.000001) //如果系数之和不为0,就将该项插入到结果中
pResult = pResult->InsertAfter(dAddCoef, pA->m_nExp);
//pA和pB都指向下一个结点
pA = pA->m_pLink;
pB = pB->m_pLink;
}
else if (pA->m_nExp < pB->m_nExp) { //如果pA指向的项的系数小于pB指向的系数
pResult = pResult->InsertAfter(pA->m_dCoef, pA->m_nExp); //就在结果中插入pA所指向的项
pA = pA->m_pLink; //并将pA指向下一结点
}
else{ //否则pB->m_nExp > pA->m_nExp
pResult = pResult->InsertAfter(pB->m_dCoef, pB->m_nExp);
pB = pB->m_pLink;
}
}
if (pA != nullptr) //如果pA没有加完(剩有大指数项)
pLast = pA; //指向剩余元素结点的指向指向pA
else //否则
pLast = pB; //指向pB
while (pLast != nullptr) { //如果pA或者pB不为空
pResult->InsertAfter(pLast->m_dCoef, pLast->m_nExp); //就将剩余元素加入到结果中
pLast = pLast->m_pLink;
}
return result;
}
CPolynomial operator * (CPolynomial& A, CPolynomial& B)
{
//将一元多项式A和B相乘,乘积9用带附加头节点的单链表表存储
//返回值为指向存储乘积多项式的单链表头指针
CPolynomial result; //用于保存结果的临时变量-用于返回
Term* pResult = result.getHead();
Term* pA = A.getHead()->m_pLink; //指向A的第一个结点
Term* pB = B.getHead()->m_pLink; //指向B的第一个结点
int AmaxExp = A.maxOrder(); //AmaxExp保存A中最大指数
int BmaxExp = B.maxOrder(); //BmaxExp保存B中最大系数
if (AmaxExp == 0) { //如果A中只有一个常数项
while (pB != nullptr) { //就将B中的每一项乘以该常数项
float tempCoef = pA->m_dCoef;
tempCoef *= pB->m_dCoef;
pResult = pResult->InsertAfter(tempCoef, pB->m_nExp);
pB = pB->m_pLink;
}
}
else if (BmaxExp == 0) { //如果B中只有一个常数项
while (pA != nullptr) { //就将A中的每一项乘以该常数项
float tempCoef = pB->m_dCoef;
tempCoef *= pA->m_dCoef;
pResult = pResult->InsertAfter(tempCoef, pA->m_nExp);
pA = pA->m_pLink;
}
}
else { //如果A、B中都函数有X项
int RmaxExp = A.maxOrder() + B.maxOrder() + 1; //注意:RmaxExp存放A与B中系数最大项之和
float *tmArray = new float[RmaxExp]; //建立一个含有RmaxExp个元素的临时数组
if (tmArray == nullptr) { //该数组的下标表示结果元素的指数
cerr << "内存分配失败!" << endl; //数组元素的数值表示该元素的系数
exit(-1);
}
for (int i = 0; i < RmaxExp; i++) //为数组初始化
tmArray[i] = 0.0;
while (pA != nullptr) { //当多项式A还未运行到最后一项
pB = B.getHead()->m_pLink; //每次循环首先将pB指向B的第一项
while(pB != nullptr){ //当多项式B还未运行到最后一项
int tempExp = pA->m_nExp + pB->m_nExp; //tempExp保存结果指数
int tempCoef = pA->m_dCoef * pB->m_dCoef; //tempCoef保存结果系数
tmArray[tempExp] += tempCoef; //将系数累加到数组中
pB = pB->m_pLink; //pB指向下一项
}
pA = pA->m_pLink; //pA指向下一项
}
for (int i = 0; i <= RmaxExp; i++) {
if (abs(tmArray[i]) > 0.000001) { //如果结果数组元素不为0
pResult = pResult->InsertAfter(tmArray[i], i); //就将该元素插入到结果中
}
}
delete[] tmArray;
}
return result;
}
main.cpp文件(测试文件)
#include"Polynomial.h"
int main() {
CPolynomial PA, PB, PC;
cout << "输入PA:" << endl;
cin >> PA;
cout << "PA = ";
cout << PA;
cout << "输入PB:" << endl;
cin >> PB;
cout <<"PB = ";
cout << PB;
CPolynomial PD;
cout << "PA+PB = ";
PD = PA + PB;
cout << PD;
cout << "PA*PB = ";
PD = PA * PB;
cout << PD;
return 0;
}
测试结果
