链表应用-一元多项式

链表应用一元多项式

说明

一元多项式 A ( x ) = a 1 x e 1 + a 2 x e 2 + a 3 x e 3 + a 4 x e 4 + ⋯ 一元多项式\\ A(x)=a_1 x^{e_1} +a_2 x^{e_2}+a_3 x^{e_3}+a_4 x^{e_4}+⋯ 一元多项式A(x)=a1xe1+a2xe2+a3xe3+a4xe4+

可以用链表存储,每个结点保存的信息为每个项的系数和指数

多项式的项

项的定义

//多项式的一项(只要数据部分)
class term
{
public:
	double coefficient;//系数
	int exponent;//指数
}

项的相关功能

构造、输出、两项相加、两项相乘

比较两项指数大小(后面多项式加法用)

class term
{
 //省略一些代码……
public:
	//重载“输出号”<<,以输出一项
	friend ostream& operator<<(ostream &out,term a);
	//构造函数
	term(double c=0, int e=0);

	/*功能:重载加号,实现两个项的相加
	* 输入:
	* a 另一个项
	* 返回:
	* 结果项,如果指数项不同则什么也不做
	* 其它:
	* 这只是多项式的一项,所以相加要求指数相同,如果指数不同则什么也不做,直接返回0,0
	*/
	term operator+(term a);
		
	/*功能:重载乘号,实现两个项的相乘
	* 返回:新的项
	* 其它:比如2x * 3x^2 = 6x^3
	*/
	term operator*(term a);
};


//比较结果
enum cmp_result
{
	less = -1,//小于
	equal = 0,//等于
	greater = 1//大于
};
/* 功能:比较两个项
* 输入:
* t1,t2两个项
* 返回:
* 比较结果
* 其它
*/
cmp_result term_cmp(term t1, term t2);

具体实现

term::term(double c, int e)
{
	coefficient = c;
	exponent = e;
}

ostream& operator<<(ostream& out, term a)
{
	//正常的多项式若有常数项,必然是第一个
	//若指数等于0,即常数项,一般只打印系数
	if (a.exponent == 0)
		out << a.coefficient;
	else
	{
		//若系数等于1,一般不再打印该系数,只打印“+”
		if (a.coefficient != 1)
		{
			out << showpos << a.coefficient;
		}
		else
			out << '+';

		out << 'x';
		//若指数等于1,一般不再打印该指数
		if (a.exponent != 1)
			out << '^' <<noshowpos<< a.exponent;
	}	
	out << ' ';		
	return out;
}

term term::operator+(term a)
{
	term t(0, 0);
	if (this->exponent == a.exponent)//只有系数相等才加,系数不等什么也不做
	{
		t.coefficient = this->coefficient + a.coefficient;
		t.exponent = this->exponent;
	}
	return t;
}

term term::operator*(term a)
{
	term t;
	t.coefficient = this->coefficient * a.coefficient;
	t.exponent = this->exponent + a.exponent;
	return t;
}


cmp_result term_cmp(term t1, term t2)
{
	if (t1.exponent < t2.exponent) return cmp_result::less;
	else if (t1.exponent == t2.exponent) return cmp_result::equal;
	else return cmp_result::greater;
}

多项式

多项式定义

显然,以各项为数据的链表即为多项式

我这里再简单封装一下

//多项式
class Polynomail
{
private:
	list<term> theTermList;//显然,以各项为数据的链表即为多项式
}

这里说明一下为什么使用双向链表list而不是单链表forward_list,按理说使用单链表就行了,不过

其一

模板forward_list插入的相关函数中没有在尾部插入pust_buck,一些时候得和常人逻辑“反过来”

其二

forward_list没有返回容器大小的函数size,使用不便

当然如果不封装,直接

typedef list<term> Polynomail

也不错

多项式相关功能

杂项

输出、构造

class Polynomail
{
//省略一些代码……
    //重载<<以输出
	friend ostream& operator<<(ostream& out, Polynomail aPolynomail);
public:
	/*
	* 功能:无参构造,什么也不做
	* 输入:
	* 返回:无
	* 其它:
	*/
	Polynomail();

	/*
	* 功能:根据已经存在的项数组,建立一元多项式P
	* 输入:
	* t:项数组指针
	* n:项的个数
	* 返回:无
	* 其它:
	* 要求项数组中,项的指数从小到大排列
	*/
	Polynomail(term* const t, uint16_t const n);

//省略一些代码……
};

实现

ostream& operator<<(ostream& out, Polynomail aPolynomail)
{
	if (!(aPolynomail.theTermList.empty()))
	{
		uint16_t number = aPolynomail.theTermList.size();
		out << "共有" << number << "项" << endl;
		list<term>::iterator it = aPolynomail.theTermList.begin();
		for (int i = 0; i < number; i++)
		{
			out << *it;
			it++;
		}		
	}
	return out;
}

Polynomail::Polynomail()
{	
}
Polynomail::Polynomail(term* const t, uint16_t const n)
{
	for (int i = 0; i < n; i++)
	{
		this->theTermList.push_back(t[i]);
	}
}
多项式加法
class Polynomail
{
//省略一些代码……
	/*功能:重载加号,完成多项式相加运算,即:Pc=Pa+Pb
	* 输入:
	* Pb:另一个多项式
	* 返回:新的多项式,即相加的结果
	* 其它:
	*/
	Polynomail operator+(Polynomail& Pb);
//省略一些代码……
};

实现

Polynomail Polynomail::operator+(Polynomail& Pb)
{
	Polynomail Pc;
	list<term>::iterator ita = this->theTermList.begin();//自己就是Pa
	list<term>::iterator itb = Pb.theTermList.begin();

	double sum = 0;
	while (ita != this->theTermList.end() && itb != Pb.theTermList.end())
	{		
		switch (term_cmp(*ita, *itb))//比较多项式的指数
		{
		case cmp_result::less://如果ita的指数比itb的小
			Pc.theTermList.push_back(*ita);//插入ita
			ita++;
			break;
		case cmp_result::greater://如果ita的指数比itb的大
			Pc.theTermList.push_back(*itb);//插入itb
			itb++;
			break;
		case cmp_result::equal://如果两项指数相等
			sum = ita->coefficient + itb->coefficient;//得到新的项的系数
			if (sum != 0)//如果系数不为零
			{
				Pc.theTermList.push_back(term(sum, ita->exponent));//插入新的项
			}
			//系数相加为0,这一项就没了,不用插入什么			
			ita++;
			itb++;
			break;		
		default:
			break;
		}
	}
	//插入Pa中剩余结点
	while (ita != this->theTermList.end())
	{
		Pc.theTermList.push_back(*ita);
		ita++;
	}
	//插入Pb中剩余结点
	while (itb != Pb.theTermList.end())
	{
		Pc.theTermList.push_back(*itb);
		itb++;
	}
	return Pc;
}

我用的教材中的多项式加法,它A(x)+B(x)之后,结果保存在A(x)中,B(x)就没了,感觉很奇怪

我这里的代码就是有一个新的多项式,结果保存在新的C(x)中

多项式乘法

乘法可以分解成一系列的加法运算
M ( x ) = A ( x ) ∗ B ( x ) = A ( x ) ∗ [ b 1 x e 1 + b 2 x e 2 + b 3 x e 3 + b 4 x e 4 + ⋯ ] = ∑ i = 1 n A ( x ) ∗ b i x e i M(x)=A(x)*B(x)\\ =A(x)*[b_1 x^{e_1} +b_2 x^{e_2}+b_3 x^{e_3}+b_4 x^{e_4}+⋯]\\ =\sum_{i=1}^n A(x)*b_i x^{e_i} M(x)=A(x)B(x)=A(x)[b1xe1+b2xe2+b3xe3+b4xe4+]=i=1nA(x)bixei
其中每一项都是一个一元多项式

先实现一元多项式和一项相乘

一元多项式和一项相乘定义

class Polynomail
{
//省略一些代码……
	/*功能:重载乘号,完成多项式和一项相乘,即:Pb=Pa*t
	* 输入:
	* t:去乘的项
	* 返回:新的多项式,即相乘的结果
	* 其它:
	*/
	Polynomail operator*(term& t);
//省略一些代码……
};

实现一元多项式和一项相乘

//重载乘号实现多项式和一项相乘
Polynomail Polynomail::operator*(term& t)
{
	Polynomail tem;
	list<term>::iterator it = this->theTermList.begin();
	uint16_t num = this->theTermList.size();
	for (uint16_t i = 0; i < num; i++)
	{
		tem.theTermList.push_back((*it) * t);//新的多项式每项为,原多项式各项乘该项
		it++;
	}
	return tem;
}

然后就可以实现多项式乘法了

多项式乘法定义

class Polynomail
{
//省略一些代码……
	/*功能:重载乘号,完成两多项式相乘,即:Pc=Pa*Pb
	* 输入:
	* Pb:另一个多项式
	* 返回:新的多项式,即相乘的结果
	* 其它:
	*/
	Polynomail operator*(Polynomail& Pb);
//省略一些代码……
};

多项式乘法实现

//两多项式相乘,即:Pa=Pa*Pb
Polynomail Polynomail::operator*(Polynomail& Pb)
{
	Polynomail Pc;//保存最终结果
	Polynomail tem;//用来进行多项式和某一项相乘
	//link它begin就是第一个存储数据的结点,最多自增Pb.size()-1次,请注意
	for (list<term>::iterator itb = Pb.theTermList.begin(); itb!=Pb.theTermList.end(); itb++)
	{
		tem = (*this) * (*itb);
		Pc = Pc + tem;
	}
	return Pc;
}
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cctv1324

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值