题目描述:
算法描述:
- 多项式结构表达:一个多项式就是一个链表,链表的每一项就是多项式的一个子项,故定义子项类
Subitem
,包含类成员项系数、阶数、指向下一项的指针,定义多项式类Multinomial
,只包含一个类成员,即指向多项式第一项的指针 - 多项式的运算分析:多项式在运算的过程中,如果多项式a加多项式b,可以看做是将多项式b的每一项依次插入到多项式a中,同理乘法可以看做多项式a,b每两项相乘后将得到的子项依次插入到一个新的多项式中。
- 多项式子项的插入:插入时根据阶数由大到小排列,插入的可能情况有四种(待插入多项式默认已经按照阶数大小排序,且合并同类项):
- 插入到第一项之前,待插入多项式的系数阶数比现有多项式的第一项还大
- 插在中间,待插入多项式的系数小于第n项,大于第n+1项
- 插在最后,待插入多项式系数小于现有所有项
- 合并同类项,若待插入多项式与第i项阶数相同,则将待插入项系数与该项系数相加即可
结果展示

问题分析:
C++
实现过程中,总会遇到许多有关类的问题,它不像java
拥有自动的垃圾回收机制,所以必须在析构函数中对申请出来的内存进行释放,而且在对象之间的相互赋值和参数传递的过程中会遇到例如深浅拷贝的问题,这个时候一个合适的拷贝构造函数就显得很重要。在参数传递的过程中要尽量使用引用类型的参数,避免多项式在深拷贝的过程中重复执行构造函数和析构函数,降低效率。- 以上实现多项式的运算实现因为要求必须使用链表,但是如果采用
hashtable
或者hashMap
这类的数据结构,相对与效率可能会有更大的进步,在插入的时候可以使用键值对的结构。
代码展示:
#ifndef TEST_MULTINOMIAL_H
#define TEST_MULTINOMIAL_H
#include <iostream>
#include <cmath>
class Subitem
{
public:
int order;
double coefficient;
Subitem *next;
Subitem(int order, double coefficient, Subitem *next = NULL)
: order(order), coefficient(coefficient), next(next)
{}
};
class Multinomial
{
public:
Subitem *startItem = NULL;
Multinomial() : startItem(NULL)
{}
Multinomial(Subitem *startItem, int mode = -1) : startItem(startItem)
{
if (mode != -1)
Create(*this);
}
Multinomial(const Multinomial &m)
{
Copy(*this, m);
}
~Multinomial()
{
Destroy(*this);
}
void Print()
{
if (startItem == NULL)
std::cout << "Empty Multinomial" << std::endl;
else
{
Subitem *currentItem = startItem;
while (currentItem != NULL)
{
if (currentItem != startItem)
{
if (currentItem->coefficient > 0)
std::cout << " + ";
else
std::cout << " - ";
std::cout << fabs(currentItem->coefficient) << "x^" << currentItem->order;
} else
std::cout << currentItem->coefficient << "x^" << currentItem->order;
currentItem = currentItem->next;
}
}
std::cout << std::endl;
}
static Multinomial &Create(Multinomial &m)
{
m = Multinomial();
int order = 0;
double coefficient = 0;
Subitem *currentItem = NULL;
std::cin >> coefficient >> order;
while (order != 0 || coefficient != 0)
{
if (coefficient != 0)
{
if (m.startItem == NULL)
{
m.startItem = new Subitem(order, coefficient);
currentItem = m.startItem;
} else
{
currentItem->next = new Subitem(order, coefficient);
currentItem = currentItem->next;
}
}
std::cin >> coefficient >> order;
}
return m;
}
static void Destroy(Multinomial &m)
{
Subitem *next = NULL;
while (m.startItem != NULL)
{
next = (*m.startItem).next;
delete m.startItem;
m.startItem = next;
}
}
static void Copy(Multinomial &des, const Multinomial &source)
{
Destroy(des);
Subitem *source_currentItem = source.startItem;
Subitem *des_currentItem = NULL;
while (source_currentItem != NULL)
{
if (des.startItem == NULL)
{
des.startItem = new Subitem(source_currentItem->order, source_currentItem->coefficient);
des_currentItem = des.startItem;
} else
{
des_currentItem->next = new Subitem(source_currentItem->order, source_currentItem->coefficient);
des_currentItem = des_currentItem->next;
}
source_currentItem = source_currentItem->next;
}
}
static Multinomial &Insert(Multinomial &m, Subitem &s)
{
if (m.startItem == NULL)
m.startItem = new Subitem(s.order, s.coefficient);
else if (s.order > m.startItem->order)
{
Subitem *startItem = new Subitem(s.order, s.coefficient);
startItem->next = m.startItem;
m.startItem = startItem;
} else```
{```
Subitem *currentIte```m = m.startItem;
while (currentItem ```!= NULL)
{```
if (s.order == ```currentItem->order)
{```
currentItem```->coefficient += s.coefficie```nt;
break;```
} else if (curr```entItem->next != NULL && s.order < curre```ntItem->order &&
s.order > currentItem->next->order)
{
Subitem *nextItem = currentItem->next;
currentItem->next = new Subitem(s.order, s.coefficient);
currentItem->next->next = nextItem;
break;
} else if (currentItem->next == NULL)
{
currentItem->next = new Subitem(s.order, s.coefficient);
break;
}
currentItem = currentItem->next;
}
}
return m;
}
static Multinomial Add(Multinomial &m1, Multinomial &m2)
{
Multinomial result = m1;
Subitem *currentItem = m2.startItem;
while (currentItem != NULL)
{
Insert(result, *currentItem);
currentItem = currentItem->next;
}
return result;
}
static Multinomial &MulWithSubItem(Multinomial &m, Subitem &s)
{
Subitem *currentItem = m.startItem;
while (currentItem != NULL)
{
currentItem->coefficient *= s.coefficient;
currentItem->order += s.order;
currentItem = currentItem->next;
}
return m;
}
static Multinomial Mul(Multinomial &m1, Multinomial &m2)
{
Multinomial result = Multinomial();
Subitem *currentItem = m2.startItem;
while (currentItem != NULL)
{
Multinomial temp = m1;
temp = MulWithSubItem(temp, *currentItem);
Subitem *s = temp.startItem;
while (s != NULL)
{
Insert(result, *s);
s = s->next;
}
currentItem = currentItem->next;
}
return result;
}
};
#endif