动态数组法实现
首先是我的运行结果,测试点四没过是我代码设计并没有考虑输入0多项式的情况,我也并不想补全这个设计漏洞了(摊手

做这道题的过程中(改bug过程中),值得念叨的点有两个:
一、构造函数的深拷贝和浅拷贝
//构造函数用来开辟空间
Poly::Poly(int MaxSize) :Data1{ new int[MaxSize] }
, Data2{ new int[MaxSize] }, MaxSize{ MaxSize }, MaxSize1{ MaxSize }{}
在构造函数中,我为动态数组开辟了内存,所以需要在析构函数中将它们delete掉
Poly::~Poly()
{
delete[] Data1;
delete[] Data2;
}
注意加法部分的代码
Poly Poly::Add(Poly P2)
{
//申请一个结果多项式P3,大小最大为P1和P2的和
Poly P3{ MaxSize + P2.MaxSize };
P3.MaxSize = 0;//申请的MaxSize不为P3非零项的个数应重置为0;
//分别指代在各个数组的循环位置
int cnt1{ 0 }, cnt2{ 0 }, cnt3{ 0 };
//两个多项式都没有被处理完
while (cnt1 != MaxSize && cnt2 != P2.MaxSize) {
//如果多项式P1的这一项的指数大于多项式P2
if (Data2[cnt1] > P2.Data2[cnt2]) {
P3.Data1[cnt3] = Data1[cnt1];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt3;
}
//如果多项式P1的这一项的指数小于多项式P2
else if (Data2[cnt1] < P2.Data2[cnt2]) {
P3.Data1[cnt3] = P2.Data1[cnt2];
P3.Data2[cnt3] = P2.Data2[cnt2];
++cnt2; ++cnt3;
}
//如果等于
else {
//而且系数相加不等于0
if (Data1[cnt1] + P2.Data1[cnt2] != 0) {
P3.Data1[cnt3] = Data1[cnt1] + P2.Data1[cnt2];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt2; ++cnt3;
}
//系数相加等于0
else {
++cnt1; ++cnt2;
}
}
}
//多项式P1有剩
if (cnt1 != MaxSize && cnt2 == P2.MaxSize) {
while (cnt1 != MaxSize) {
P3.Data1[cnt3] = Data1[cnt1];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt3;
}
P3.MaxSize = cnt3;
return P3;
}
//多项式P2有剩
else if (cnt1 == MaxSize && cnt2 != P2.MaxSize) {
while (cnt2 != P2.MaxSize) {
P3.Data1[cnt3] = P2.Data1[cnt2];
P3.Data2[cnt3] = P2.Data2[cnt2];
++cnt2; ++cnt3;
}
P3.MaxSize = cnt3;
return P3;
}
//刚好都没得剩
else {
P3.MaxSize = cnt3;
return P3;
}
}
P3是定义在函数内部的局部变量,函数实际上返回的是P3的拷贝,函数执行完成后P3自动调用析构函数。我一开始并没有重写拷贝构造函数,那么类本身会有一个默认的拷贝构造函数,这个拷贝构造函数执行的是浅拷贝,那么也就导致这样一个问题,P3的拷贝P4内的带指针成员拷贝的是P3的指针,在P3被析构后,这些指针对象被释放掉了,而P4也是一个右值,它在执行完毕后也会自动调用析构函数,那么就会出现对其指针成员的两次delete,这将导致程序崩溃!!!
所以,在类含有指针对象的成员时,最好自己实现拷贝构造函数,以完成深拷贝,避免不必要的错误。
二、用递归实现乘法运算
这个好像~~~也没什么好讲的,注意一下递归结束的条件以及对类的MaxSize复原就好了
下面是完整代码
#include<iostream>
using namespace std;
//动态数组实现
class Poly
{
public:
//多项式的默认构造函数,默认为空
Poly(int MaxSize = 0);
//输入数字以改变数组内容
Poly& Input();
//增加拷贝构造函数
Poly(const Poly& P);//深拷贝
//析构函数,释放数组
~Poly();
//多项式的加法
Poly Add(Poly P2);
//多项式的乘法
Poly Multiply(const Poly& P2);
//多项式计算结果展示
void show();
private:
//系数数组
int* Data1;
//指数数组
int* Data2;
//说明数组的大小
int MaxSize;
//MaxSize的备份,用于乘法运算的复原操作
int MaxSize1;
};
//构造函数用来开辟空间
Poly::Poly(int MaxSize) :Data1{ new int[MaxSize] }
, Data2{ new int[MaxSize] }, MaxSize{ MaxSize }, MaxSize1{ MaxSize }{}
Poly::Poly(const Poly& P) : Data1{ new int[P.MaxSize] }, Data2{ new int[P.MaxSize] }
{
for (int i = 0; i < P.MaxSize; ++i) {
Data1[i] = P.Data1[i];
Data2[i] = P.Data2[i];
}
MaxSize = P.MaxSize;
}
Poly& Poly::Input()
{
int a, b;//分别为系数和指数
for (int i = 0; i < MaxSize; ++i) {
cin >> a >> b;
Data1[i] = a;
Data2[i] = b;
}
return *this;
}
Poly::~Poly()
{
delete[] Data1;
delete[] Data2;
}
Poly Poly::Add(Poly P2)
{
//申请一个结果多项式P3,大小最大为P1和P2的和
Poly P3{ MaxSize + P2.MaxSize };
P3.MaxSize = 0;//申请的MaxSize不为P3非零项的个数应重置为0;
//分别指代在各个数组的循环位置
int cnt1{ 0 }, cnt2{ 0 }, cnt3{ 0 };
//两个多项式都没有被处理完
while (cnt1 != MaxSize && cnt2 != P2.MaxSize) {
//如果多项式P1的这一项的指数大于多项式P2
if (Data2[cnt1] > P2.Data2[cnt2]) {
P3.Data1[cnt3] = Data1[cnt1];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt3;
}
//如果多项式P1的这一项的指数小于多项式P2
else if (Data2[cnt1] < P2.Data2[cnt2]) {
P3.Data1[cnt3] = P2.Data1[cnt2];
P3.Data2[cnt3] = P2.Data2[cnt2];
++cnt2; ++cnt3;
}
//如果等于
else {
//而且系数相加不等于0
if (Data1[cnt1] + P2.Data1[cnt2] != 0) {
P3.Data1[cnt3] = Data1[cnt1] + P2.Data1[cnt2];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt2; ++cnt3;
}
//系数相加等于0
else {
++cnt1; ++cnt2;
}
}
}
//多项式P1有剩
if (cnt1 != MaxSize && cnt2 == P2.MaxSize) {
while (cnt1 != MaxSize) {
P3.Data1[cnt3] = Data1[cnt1];
P3.Data2[cnt3] = Data2[cnt1];
++cnt1; ++cnt3;
}
P3.MaxSize = cnt3;
return P3;
}
//多项式P2有剩
else if (cnt1 == MaxSize && cnt2 != P2.MaxSize) {
while (cnt2 != P2.MaxSize) {
P3.Data1[cnt3] = P2.Data1[cnt2];
P3.Data2[cnt3] = P2.Data2[cnt2];
++cnt2; ++cnt3;
}
P3.MaxSize = cnt3;
return P3;
}
//刚好都没得剩
else {
P3.MaxSize = cnt3;
return P3;
}
}
Poly Poly::Multiply(const Poly& P2)
{
if (MaxSize == 1) {//递归结束条件
Poly P3{ P2.MaxSize };
for (int i = 0; i < P2.MaxSize; ++i) {
P3.Data1[i] = Data1[MaxSize - 1] * P2.Data1[i];
P3.Data2[i] = Data2[MaxSize - 1] + P2.Data2[i];
}
MaxSize = MaxSize1;//乘法运算结束后复原MaxSize
return P3;
}
else {
Poly P3{ P2.MaxSize };
for (int i = 0; i < P2.MaxSize; ++i) {
P3.Data1[i] = Data1[MaxSize - 1] * P2.Data1[i];
P3.Data2[i] = Data2[MaxSize - 1] + P2.Data2[i];
}
--MaxSize;
return this->Multiply(P2).Add(P3);
}
}
void Poly::show()
{
//是空多项式的话
if (MaxSize == 0) {
cout << 0 << ' ' << 0;
}
else {//不是的话
for (int i = 0; i < MaxSize - 1; ++i) {
cout << Data1[i] << ' ' << Data2[i] << ' ';
}
cout << Data1[MaxSize - 1] << ' ' << Data2[MaxSize - 1];
}
}
int main()
{
/*输入N1,构造出多项式P1*/
int N1;
cin >> N1;
Poly P1{ N1 };
P1.Input();
/*输入N2,构造出多项式P2*/
int N2;
cin >> N2;
Poly P2{ N2 };
P2.Input();
/*P1乘P2*/
P1.Multiply(P2).show();
/*P1加P2*/
cout << endl;
P1.Add(P2).show();
return 0;
}
本文讲述了作者在实现多项式动态数组运算过程中遇到的构造函数深浅拷贝问题,以及如何通过自定义拷贝构造函数避免内存泄露。重点讨论了加法运算的实现和乘法递归中的注意事项。

126

被折叠的 条评论
为什么被折叠?



