[Implementation of linked list] Addition and multiplication of polynomials of one variable [Detailed explanation of addition and multiplication]

Table of contents

1. Representation of one-variable polynomials

1. Concept

2. What data structure is used to implement it?

2. Implementation of one-variable polynomials

1. Basic structure overview

2. Create a one-variable polynomial

3. End insertion of nodes

4. Addition of polynomials of one variable

5. Multiplication of polynomials of one variable

6. Printing of polynomials

 7. Poly’s destructor

8. Complete code

Poly.h:

Poly.cpp 

test.cpp

9. Run the test

3. Difficult debugging process (you don’t have to watch it, I watched it myself)


1. Representation of one-variable polynomials

1. Concept

Form:Pn(x) = P0 + P1x + p2X^2 + ...... + Pnx^n Called nth degree polynomial

N阶多项式Pn(x)Yes n+1 项

  • Series:P0,P1,P2,...Pn
  • Index:0,1,2,......,n,按升幂Order

2. What data structure is used to implement it?

It can be seen that usingsequence list will waste space, so uselinked list< a i=4>to store

ThatGood point

  • The number of terms of the polynomial can grow dynamically, and there is no storage overflow problem.
  • Easy to insert and delete without moving data

2. Implementation of one-variable polynomials

Implemented in three files

Poly.h    Poly.cpp    test.cpp

1. Basic structure overview

//链表的多项式节点
struct Polynode
{
	int _coef;//系数
	int _exp;//指数
	struct Polynode* _next;

	Polynode(int coef = 0,int exp = 0)
		:_next(nullptr)
		,_coef(coef)
		,_exp(exp)
	{}

	~Polynode()
	{
		_next = nullptr;
	}
};

//一元多项式
class Poly
{
public:
	void CreatePoly();//创建
	void Print();//打印
	void Push_back(Polynode* node);//尾插
	void AddPoly(Poly& p2, Poly& sum);//相加
	void MultiPoly(Poly& p2, Poly& sum);//相乘
	~Poly();//析构
private:
	Polynode* _head = new Polynode;//直接开辟个头结点
};

2. Create a one-variable polynomial

Continuously create new nodesTail insertion is enough, but please note if the input coefficient is 0 , there is no need to insert this node, just continue

//创建一元多项式
void Poly::CreatePoly()
{
	Polynode* tail = _head;//尾节点
	int n = 0;
	cout << "请输入一元多项式的项数:" << endl;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		int cof, exp;
		cin >> cof >> exp;
		if (cof == 0)
			continue;//如果系数==0,则不插入此节点
		Polynode* newnode = new Polynode(cof, exp);//创建新节点
		tail->_next = newnode;//链接
		tail = newnode;
	}
}

3. End insertion of nodes

//节点的尾插
void Poly::Push_back(Polynode* node)
{
	Polynode* tail = _head->_next;
	if (tail == nullptr)
	{//若链表为空,直接插入
		_head->_next = node;
	}
	else
	{
		while (tail->_next)
		{	//找到尾节点
			tail = tail->_next;
		}
		tail->_next = node;
	}
}

4. Addition of polynomials of one variable

//一元多项式的相加(利用一元多项式指数是升序的特点)
//p1 + p2
void Poly::AddPoly(Poly& p2,Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	Polynode* head = sum._head;
	while (cur1 && cur2)
	{	//都不为空才会进入循环
		//1、p1的指数<p2的指数
		//2、p1的指数>p2的指数
		//3、p2的指数=p2的指数:
		//   ①、系数相加为0,删除cur1和cur2的对应节点 
		//   ②、不为0,加和到cur1上,尾插到sum后面
		if (cur1->_exp < cur2->_exp)
		{
			head->_next = cur1;
			head = cur1;
			cur1 = cur1->_next;
		}
		else if (cur1->_exp > cur2->_exp)
		{
			head->_next = cur2;
			head = cur2;
			cur2 = cur2->_next;
		}
		else
		{
			//①、系数相加为0
			if (cur1->_coef + cur2->_coef == 0)
			{
				Polynode* next1 = cur1->_next;
				Polynode* next2 = cur2->_next;
				delete cur1;
				delete cur2;
				cur1 = next1;
				cur2 = next2;
			}
			else
			{//②、系数相加不为0
				cur1->_coef = cur1->_coef + cur2->_coef;
				head->_next = cur1;
				head = cur1;
				cur1 = cur1->_next;
				Polynode* next = cur2->_next;
				delete cur2;
				cur2 = next;
			}
		}
	}
	if (cur1)
	{//若cur1不为空
		head->_next = cur1;
	}
	if (cur2)
	{//若cur2不为空
		head->_next = cur2;
	}
}

5. Multiplication of polynomials of one variable

 The logic of multiplication isdouble-level loop, for linked listHow to do a double loop? The idea is to multiply the first term of the first polynomial by each term of the second polynomial, and then multiply the second term of the first polynomial by the second term. Each term of a polynomial....until the end of the multiplication

//一元多项式的相乘
//p1 * p2
void Poly::MultiPoly(Poly& p2, Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	int cofs = 0, exps = 0;
	while (cur1)
	{
		cur2 = (p2._head)->_next;//再次回到头结点的下一位置
		while (cur2)
		{
			cofs = cur1->_coef * cur2->_coef;//系数相乘
			exps = cur1->_exp + cur2->_exp;//指数相加
			Polynode* newnode = new Polynode(cofs, exps);
			sum.Push_back(newnode);
			
			cur2 = cur2->_next;
		}
		cur1 = cur1->_next;
	}
}

6. Printing of polynomials

 There are special circumstances to consider:

① If the coefficient is 1 and the index is not 0, only the x^ index will be printed.

②. If the coefficient is 1 and the index is 0, only 1 will be printed.

③. If the coefficient is not 0 and the index is 0, only the coefficient will be printed.

④. If the coefficient is a negative number, add () to the coefficient

//打印一元多项式
void Poly::Print( )
{
	Polynode* cur = _head->_next;
	while (cur)
	{
		//当指数!=0时,才会打印出x
		if (cur->_exp != 0)
		{
			//当系数!=1时,才会打印出系数
			if (cur->_coef != 1)
			{
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")x^" << cur->_exp;
				}
				else
				{
					cout << cur->_coef;
					cout << "x^" << cur->_exp;
				}
			}
			else
			{//当系数==1时,指数不为0时
				cout << "x^" << cur->_exp;
			}
		}
		else
		{ //若指数为0,只打印系数
			if (cur->_coef != 1)
			{//系数不为1,则只打印系数
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")";
				}
				else
				{
					cout << cur->_coef;
				}
			}
			else
			{
				cout << "1";//若系数为1,指数为0,则打印1
			}
		}
		cur = cur->_next;

		if (cur != NULL)
		{//最后一项之前才会打印加号
			cout << " + ";//正数打印+
		}
	}
	cout << endl;
}

 7. Poly’s destructor

//析构函数
Poly::~Poly()
{
	delete _head;
	_head = nullptr;
}

8. Complete code

Poly.h:

#pragma once
#include<iostream>
using namespace std;
//链表的多项式节点
struct Polynode
{
	int _coef;//系数
	int _exp;//指数
	struct Polynode* _next;

	Polynode(int coef = 0,int exp = 0)
		:_next(nullptr)
		,_coef(coef)
		,_exp(exp)
	{}

	~Polynode()
	{
		_next = nullptr;
	}
};

//一元多项式
class Poly
{
public:
	void CreatePoly();//创建
	void Print();//打印
	void Push_back(Polynode* node);//尾插
	void AddPoly(Poly& p2, Poly& sum);//相加
	void MultiPoly(Poly& p2, Poly& sum);//相乘
	~Poly();//析构
private:
	Polynode* _head = new Polynode;//直接开辟个头结点
};

Poly.cpp 

#include"Poly.h"

//创建一元多项式
void Poly::CreatePoly()
{
	Polynode* tail = _head;//尾节点
	int n = 0;
	cout << "请输入一元多项式的项数:" << endl;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		int cof, exp;
		cin >> cof >> exp;
		if (cof == 0)
			continue;//如果系数==0,则不插入此节点
		Polynode* newnode = new Polynode(cof, exp);//创建新节点
		tail->_next = newnode;//链接
		tail = newnode;
	}
}

//打印一元多项式
void Poly::Print( )
{
	Polynode* cur = _head->_next;
	while (cur)
	{
		//当指数!=0时,才会打印出x
		if (cur->_exp != 0)
		{
			//当系数!=1时,才会打印出系数
			if (cur->_coef != 1)
			{
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")x^" << cur->_exp;
				}
				else
				{
					cout << cur->_coef;
					cout << "x^" << cur->_exp;
				}
			}
			else
			{//当系数==1时,指数不为0时
				cout << "x^" << cur->_exp;
			}
		}
		else
		{ //若指数为0,只打印系数
			if (cur->_coef != 1)
			{//系数不为1,则只打印系数
				if (cur->_coef < 0)
				{
					cout << "(" << cur->_coef;
					cout << ")";
				}
				else
				{
					cout << cur->_coef;
				}
			}
			else
			{
				cout << "1";//若系数为1,指数为0,则打印1
			}
		}
		cur = cur->_next;

		if (cur != NULL)
		{//最后一项之前才会打印加号
			cout << " + ";//正数打印+
		}
	}
	cout << endl;
}

//节点的尾插
void Poly::Push_back(Polynode* node)
{
	Polynode* tail = _head->_next;
	if (tail == nullptr)
	{//若链表为空,直接插入
		_head->_next = node;
	}
	else
	{
		while (tail->_next)
		{	//找到尾节点
			tail = tail->_next;
		}
		tail->_next = node;
	}
}

//一元多项式的相加(利用一元多项式指数是升序的特点)
//p1 + p2
void Poly::AddPoly(Poly& p2,Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	Polynode* head = sum._head;
	while (cur1 && cur2)
	{	//都不为空才会进入循环
		//1、p1的指数<p2的指数
		//2、p1的指数>p2的指数
		//3、p2的指数=p2的指数:
		//   ①、系数相加为0,删除cur1和cur2的对应节点 
		//   ②、不为0,加和到cur1上,尾插到sum后面
		if (cur1->_exp < cur2->_exp)
		{
			head->_next = cur1;
			head = cur1;
			cur1 = cur1->_next;
		}
		else if (cur1->_exp > cur2->_exp)
		{
			head->_next = cur2;
			head = cur2;
			cur2 = cur2->_next;
		}
		else
		{
			//①、系数相加为0
			if (cur1->_coef + cur2->_coef == 0)
			{
				Polynode* next1 = cur1->_next;
				Polynode* next2 = cur2->_next;
				delete cur1;
				delete cur2;
				cur1 = next1;
				cur2 = next2;
			}
			else
			{//②、系数相加不为0
				cur1->_coef = cur1->_coef + cur2->_coef;
				head->_next = cur1;
				head = cur1;
				cur1 = cur1->_next;
				Polynode* next = cur2->_next;
				delete cur2;
				cur2 = next;
			}
		}
	}
	if (cur1)
	{//若cur1不为空
		head->_next = cur1;
	}
	if (cur2)
	{//若cur2不为空
		head->_next = cur2;
	}
}

//一元多项式的相乘
//p1 * p2
void Poly::MultiPoly(Poly& p2, Poly& sum)
{
	Polynode* cur1 = _head->_next, * cur2 = (p2._head)->_next;//cur用来遍历
	int cofs = 0, exps = 0;
	while (cur1)
	{
		cur2 = (p2._head)->_next;//再次回到头结点的下一位置
		while (cur2)
		{
			cofs = cur1->_coef * cur2->_coef;//系数相乘
			exps = cur1->_exp + cur2->_exp;//指数相加
			Polynode* newnode = new Polynode(cofs, exps);
			sum.Push_back(newnode);
			
			cur2 = cur2->_next;
		}
		cur1 = cur1->_next;
	}
}

//析构函数
Poly::~Poly()
{
	delete _head;
	_head = nullptr;
}

test.cpp

#include"Poly.h"

void TestPoly()
{
	Poly p1,p2,sum1,sum2;
	p1.CreatePoly();
	p2.CreatePoly();
	p1.Print();
	p2.Print();

	cout << endl;
	cout << "p1 * p2的结果为" << endl;
	p1.MultiPoly(p2, sum2);
	sum2.Print();

	cout << endl;
	cout << "p1 + p2的结果为" << endl;
	p1.AddPoly(p2,sum1);
	sum1.Print();
}

int main()
{
	TestPoly();

	return 0;
}

9. Run the test

 

Finally, there is still a problem with the code. After the x terms with the same exponent are added, they are not merged after multiplication. I will not write it here. 

3. Difficult debugging process (you don’t have to watch it, I watched it myself)

After I finished writing the polynomial addition, the program stuck for me directly after creating the polynomial. However, the previous test printout was fine. The problem may have occurred in AddPoly.

After debugging, I found that there is a problem with the insertion of AddPoly. I don’t know when to delete the node during tail insertion and whether the node should not be deleted.

After the AddPoly code logic was modified, another problem occurred: However, there was no call to Addpoly, and the code still had no problem printing p2. This means that there was a problem with the printing of p2 after AddPoly was added. There may be a problem with deletion.

After constant debugging, I found that the problem lies in the order of calls, because part of the data of p2 or p1 will be deleted after calling AddPoly. Therefore, if you want to print p1 and p2, you must call it before calling AddPoly, otherwise it will be illegal access. This is a small problem

 Something went wrong again when implementing multiplication

 But if you comment out AddPoly, you can run MultiPoly normally, but the problem is still the same. AddPoly should be called at the end, because it destroys p1 or p2, or you can multiply and change the data without p1 and p2.

The problem can be solved by adding them at the end when calling.

Guess you like

Origin blog.csdn.net/m0_74044018/article/details/133185982