Table of contents
1. Representation of one-variable polynomials
2. What data structure is used to implement it?
2. Implementation of one-variable polynomials
2. Create a one-variable polynomial
4. Addition of polynomials of one variable
5. Multiplication of polynomials of one variable
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.