如何利用线性表?完成一元多项式运算【内容丰富,简单易懂】


🍀🍀🍀🍀🍀🍀本篇干货满满哦~

在学习线性表时遇到了一个有趣的例子:如何用线性表来完成一元多项式的算数实现?

🍀🍀🍀🍀 🍀🍀


多项式我们知道,每项形式均为\[ coef \cdot x ^{exp}, \]coef是该项系数,exp是变元x的指数

🍎本篇程序所包含到的内容:单循环链表结构体模板类模板友元函数以及运算符重载

这里先给大家放几张程序实现的截图

1、多项式的输入与输出

2、多项式的加法运算

3、多项式的乘法运算


具体程序实现👇

目录

🍎程序设计思路

🍎项结点实现

🍎多项式类

🍎多项式的输入和输出

🍎多项式相加

🍎多项式相乘

🍎重载运算符

末尾📖

源码


  • 程序设计思路

    将一个多项式看成一个线性表,线性表的元素就是多项式的项。对多项式算术运算而言,连接存储方式更合适。一般来来说,多项式的项数和指数变化较大,难以确定,若采用顺序存储方式,需要先分配足够空间,容易造成空间浪费;而采取链接存储方式,动态创建新结点以存储多项式的项,就十分灵活。


  • 项结点实现

    设每个项结点Term有三个域:系数(coef)、指数(exp)和指向后继结点的指针(link),由此类节点构造带表头结点的单循环链表,存储一个多项式。

    Term类包含三个数据成员coef、exp和link,两个构造函数以及如下定义的成员函数

Term* InsertAfter(T c, int e);

  •      Term* InsertAfter(T c, int e);
  •      后置条件:构造一个新项结点 < c , e >,并插在前结点及其后继之间,函数返回新项结点地址。

template <typename T>
struct Term {
	Term(int e) :exp(e),coef(0) { this->link = NULL; }
	Term(T c, int e, Term* next) :coef(c), exp(e) { this->link = next; }
	Term* InsertAfter(T c, int e);

	T coef;		//系数
	int exp;	//指数
	Term* link;	//下一项
};

template< typename T>
Term<T>* Term<T>::InsertAfter(T c, int e) {
	link = new Term(c, e, link);
	return link;
}

  • 多项式类

    多项式类Polynominal只有一个数据成员theList,它是指向单循环链表的表头结点的指针,函数成员包括构造函数和析构函数,AddTerms、Output、PolyAdd和PolyMul函数,以及重载 “<<” “>>” “=” 运算符。

  • 构造函数建立只有一个表头结点,其coef值域为0,exp值域为-1,link值域为指向自身,形成只有表头结点空单循环链表(可参考上图单循环链表)。析构函数调用Clear函数,释放一个多项式链表中的全部结点,再将表头收回;
  • AddTerms函数通过输入流in,输入多项式各项,构造一个多项式;
  • Output函数将多项式送输出流;
  • 重载 “<<” 和 “>>” 运算符函数是Polynominal的友元函数,它们的功能分别于AddTerms和Output函数相同,只是为了简化程序书写形式而设计;
  • PolyAdd函数将多项式 p( x ) 和 q ( x )相加,结果为多项式 *this;
  • PolyMul函数将多项式 p( x ) 和 q ( x )相乘,结果为多项式 *this;
template<typename T>
class Polynominal {
public:
	Polynominal();
	~Polynominal();
	void AddTerms(istream& in);		//输入多项式
	void Output(ostream& out)const;	//输出多项式
	Polynominal& PolyAdd(const Polynominal& x, const Polynominal& y);	//多项式加法
	Polynominal& PolyMul(const Polynominal& x, const Polynominal& y);	//多项式相乘
	void operator=(const Polynominal&x);		//重载“=”运算符
	void Clear();
private:
	Term<T>* theList;
	friend ostream& operator<<(ostream&, const Polynominal);
	friend ostream& operator>>(ostream&, Polynominal);
};

template<typename T>
Polynominal<T>::Polynominal() {
	theList = new Term<T>(-1);
	theList->link = theList;
}

template<typename T>
Polynominal<T>::~Polynominal() {
	Clear();
	delete theList;
}

template<typename T>
void Polynominal<T>::Clear() {
	Term<T>* q = theList, * r;
	for (r = q->link; r != theList; r = q->link) {
		q->link = r->link;
		delete r;
	}
}

  • 多项式的输入和输出

    使用AddTerms函数,可以根据需要,从输入流in向一个空多项式添加各项,构成一个多项式(注意,为了简化算法,算法中未包含将用户输入多项式按降幂数据存储的代码) 。

    使用Output函数将多项式送输出流,从而输出一个多项式。多项式\[3x^{14}+6x^{2}+2  \]以下列形式输出:3x^14+6x^2+2。

  • AddTerms函数从输入流逐个输入多项式的项(系数c和指数e),以输入负指数作为多项式的结束条件。AddTerms函数调用Term类的成员函数InsertAfter(c , e) 构造一个新项结顶,并将其添加到但虚幻链表尾部。初始时,指针q指向空单循环链表的表头结点,新项结顶将插在q指示的结点之后。InsertAfter函数返回新项结点的地址,该地址值被赋给指针q,因此,指针q始终指向尾结点。
  • Output函数调用在Term类上重载的 “<<” 运算符。如果高次幂是整系数,则按多项式书写的习惯不打印 “ + ” ;否则,对于非高次幂项,当系数为正时,系数前需另加 “ + ” 号。

template< typename T>
void Polynominal<T>::AddTerms(istream& in) {
	Term<T>* q = theList;
	T c;
	int e;
	cout << "输入多项式系数与指数(coef,exp),指数为负数时停止输入\n" << endl;
	for (;;) {
		
		cin >> c >> e;
		if (e < 0)	//如果e为负值,输入完毕
			break;
		q = q->InsertAfter(c, e);
	}
}

template<typename T>
void Polynominal<T>::Output(ostream& out)const {
	bool start = true;
	Term<T>* p = theList->link;
	for (; p != theList; p=p->link) {
		if (!start && p->coef > 0)
			out << '+';
		start = false;
		out << *p;    //调用Term类上重载的 “<<” 运算符
	}
	out << endl;
}

//Term类上重载 “<<” 运算符
template <typename T>
ostream& operator<<(ostream& out, const Term<T>& val) {
	if (val.coef == 0)
		return out;
	switch (val.exp) {
	case 0:
		out << val.coef;
		break;
	case 1:
		if (val.coef != 1)
			out << val.coef;
		out << "X";
		break;
	default:
		if (val.coef != 1)
			out << val.coef;
		out << "X^"<<val.exp;
		break;
	}
	return out;
}

  • 多项式相加

一元系数多项式相加的例子如图,图中d(x) = a(x) + b(x) ,均为多项式

     PolyAdd函数实现一元多项式 x 于 y 的相加,当前多项式对象 *this 是两者之和,该函数返回和多项式。三个多项式都用带头结点的单循环链表表示。初始时,应清空 *this 多项式。

    指针p和q分别指向多项式x和y的当前正在进行比较的项。初始时,它们分别指向多项式的第一项,指针t指向多项式 *this 的表头结点。PolyAdd函数调用ExpComp函数事项两项达到指数间的比较。

    现将p指示的项的指数 p->exp 于q指示的项的指数 q->exp进行比较,有三种可能的结果,每种结果都需要调用InsertAfter函数,在多项式 *this 的末尾添加新项的结点,并且指针t始终指向多项式 *this 的尾部。三种可能的比较结果如下。

  1. p -> exp == q -> exp,则合并同类项目=。如果此时 q -> coef + p ->coef != 0,则在多项式 *this 的最后添加新项结点,其系数为q -> coef + p ->coef ,指数为 p -> exp,指针p和q均后移一项。
  2. p -> exp > q -> exp,则在多项式 *this 的最后添加新项结点,其系数为 p ->coef ,指数为 p -> exp,指针p后移一项。
  3. p -> exp < q -> exp,则在多项式 *this 的最后添加新项结点,其系数为 q ->coef ,指数为 q -> exp,指针q后移一项。 
int ExpComp(int x, int y) {
	if (x == y)
		return 0;
	else if (x > y)
		return 1;
	else
		return -1;
}

template<typename T>
Polynominal<T>& Polynominal<T>::PolyAdd(const Polynominal<T>& x, const Polynominal<T>& y) {
	Clear();
	Term<T>* t = theList, * p = x.theList->link, * q = y.theList->link;
	while (p->exp >= 0 || q->exp >= 0) {
		switch (ExpComp(p->exp, q->exp)) {
		case -1:
			t->InsertAfter(q->coef, q->exp);
			q = q->link;
			break;
		case 0:
			if (p->coef + q->coef != 0) 
				t = t->InsertAfter(p->coef + q->coef, p->exp);
			p = p->link;
			q = q->link;
			break;
		case 1:
			t->InsertAfter(p->coef, p->exp);
			p = p->link;
			break;
		}
	}
	return *this;
}

  • 多项式相乘

大家早已熟知,乘法可以通过加法来实现。事实上,只需将被乘数多项式分别于乘数多项式的每项相乘,然后将所得的多项式相加,就可求两个多项式的乘积。例如,

template<typename T>
Polynominal<T>& Polynominal<T>::PolyMul(const Polynominal& x, const Polynominal& y) {
	Clear();
	Polynominal<T> s, t;
	Term<T>* q, * p = y.theList->link;
	for (; p != y.theList; p = p->link) {
		s = x;
		for (q = s.theList->link; q != s.theList; q = q->link) {
			q->coef = p->coef * q->coef;
			q->exp = p->exp + q->exp;
		}
		t = PolyAdd(s, t);
	}
	return *this;
}
  • 重载运算符

    重载 赋值(=) 和输出(>>) 输出(<<)运算符。重载这几个运算符可以简化程序。重载赋值运算符为了防止浅拷贝问题。

template<typename T>
ostream& operator<<(ostream& out, const Polynominal<T>& x) {
	x.Output(out);
	return out;
}

template<typename T>
ostream& operator>>(istream& in,  Polynominal<T>& x) {
	x.AddTerms(in);
	return in;
}
template<typename T>
void Polynominal<T>::Output(ostream& out)const {
	bool start = true;
	Term<T>* p = theList->link;
	for (; p != theList; p=p->link) {
		if (!start && p->coef > 0)
			out << '+';
		start = false;
		out << *p;
	}
	out << endl;
}

末尾📖

如果有帮助的话麻烦点个赞鼓励一下!

#include<iostream>
using namespace std;


template <typename T>
struct Term {
	Term(int e) :exp(e),coef(0) { this->link = NULL; }
	Term(T c, int e, Term* next) :coef(c), exp(e) { this->link = next; }
	Term* InsertAfter(T c, int e);


	T coef;		//系数
	int exp;	//指数
	Term* link;	//下一项
};

template< typename T>
Term<T>* Term<T>::InsertAfter(T c, int e) {
	link = new Term(c, e, link);
	return link;
}


template <typename T>
ostream& operator<<(ostream& out, const Term<T>& val) {
	if (val.coef == 0)
		return out;
	switch (val.exp) {
	case 0:
		out << val.coef;
		break;
	case 1:
		if (val.coef != 1)
			out << val.coef;
		out << "X";
		break;
	default:
		if (val.coef != 1)
			out << val.coef;
		out << "X^"<<val.exp;
		break;
	}
	return out;
}

template<typename T>
class Polynominal {
public:
	Polynominal();
	~Polynominal();
	void AddTerms(istream& in);		//输入多项式
	void Output(ostream& out)const;	//输出多项式
	Polynominal& PolyAdd(const Polynominal& x, const Polynominal& y);	//多项式加法
	Polynominal& PolyMul(const Polynominal& x, const Polynominal& y);	//多项式相乘
	void operator=(const Polynominal&x);		//重载“=”运算符
	void Clear();
private:
	Term<T>* theList;
	friend ostream& operator<<(ostream&, const Polynominal);
	friend ostream& operator>>(istream&, Polynominal);
};

template<typename T>
Polynominal<T>::Polynominal() {
	theList = new Term<T>(-1);
	theList->link = theList;
}

template<typename T>
Polynominal<T>::~Polynominal() {
	Clear();
	delete theList;
}

template<typename T>
void Polynominal<T>::Clear() {
	Term<T>* q = theList, * r;
	for (r = q->link; r != theList; r = q->link) {
		q->link = r->link;
		delete r;
	}
}

template< typename T>
void Polynominal<T>::AddTerms(istream& in) {
	Term<T>* q = theList;
	T c;
	int e;
	cout << "输入多项式系数与指数(coef,exp),指数为负数时停止输入\n" << endl;
	for (;;) {
		
		cin >> c >> e;
		if (e < 0)	//如果e为负值,输入完毕
			break;
		q = q->InsertAfter(c, e);
	}
}

template<typename T>
ostream& operator<<(ostream& out, const Polynominal<T>& x) {
	x.Output(out);
	return out;
}

template<typename T>
ostream& operator>>(istream& in,  Polynominal<T>& x) {
	x.AddTerms(in);
	return in;
}
template<typename T>
void Polynominal<T>::Output(ostream& out)const {
	bool start = true;
	Term<T>* p = theList->link;
	for (; p != theList; p=p->link) {
		if (!start && p->coef > 0)
			out << '+';
		start = false;
		out << *p;
	}
	out << endl;
}

int ExpComp(int x, int y) {
	if (x == y)
		return 0;
	else if (x > y)
		return 1;
	else
		return -1;
}


template<typename T>
Polynominal<T>& Polynominal<T>::PolyAdd(const Polynominal<T>& x, const Polynominal<T>& y) {
	Clear();
	Term<T>* t = theList, * p = x.theList->link, * q = y.theList->link;
	while (p->exp >= 0 || q->exp >= 0) {
		switch (ExpComp(p->exp, q->exp)) {
		case -1:
			t->InsertAfter(q->coef, q->exp);
			q = q->link;
			break;
		case 0:
			if (p->coef + q->coef != 0) 
				t = t->InsertAfter(p->coef + q->coef, p->exp);
			p = p->link;
			q = q->link;
			break;
		case 1:
			t->InsertAfter(p->coef, p->exp);
			p = p->link;
			break;
		}
	}
	return *this;
}


template<typename T>
void Polynominal<T>::operator=(const Polynominal<T>& x) {
	if (this == &x)//防止自我拷贝
		return;
	Clear();
	Term<T>* q = theList, * p = x.theList->link;
	for (; p != x.theList; p = p->link)
		q = q->InsertAfter(p->coef, p->exp);
}


template<typename T>
Polynominal<T>& Polynominal<T>::PolyMul(const Polynominal& x, const Polynominal& y) {
	Clear();
	Polynominal<T> s, t;
	Term<T>* q, * p = y.theList->link;
	for (; p != y.theList; p = p->link) {
		s = x;
		for (q = s.theList->link; q != s.theList; q = q->link) {
			q->coef = p->coef * q->coef;
			q->exp = p->exp + q->exp;
		}
		t = PolyAdd(s, t);
	}
	return *this;
}


int main() {
	Polynominal<int>a;
	a.AddTerms(cin);
	Polynominal<int>b;
	b.AddTerms(cin);
	cout << "输入:\n" << endl;
	cout << "多项式q(x)=";
	a.Output(cout);
	cout << "多项式p(x)=";
	b.Output(cout);
	cout << "\n输出:\n";
	Polynominal<int>c;
	c.PolyMul(a, b);
	cout << "q(x)×p(x)=";
	c.Output(cout);
	system("pause");
	return 0;
	
}

 

  • 13
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值