02-线性结构2 一元多项式的乘法与加法运算
分数 20
作者 DS课程组
单位 浙江大学
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0
。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
解法一:用链表求解,这是暑假学数据结构的时候写的,我现在看着头都晕,如果考试的时候用这方法写的话,能够考个高分,真的很佩服他的。因此,我这几天刷PTA算法集又遇到了这个题目,就用结构题来求解一下。详见解法二:
对于链表求解的题目,如果要重新存储数据,就得申请空间进行存储,并且不应该直接将原链表的结点赋给新节点,否则会造成原链表的信息丢失或者改变,除非只需要一个链表的时候就可以将原链表赋给新节点。
同时,也学会了几个单词:
polygon: 多角形,多边形
int coff; //cofficient:系数,共同作用的;
int exp; //exponent : 指数;
typedef PtrPolyNode Polynomial; //polynomial : 多项式
//AC
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef struct PolyNode* PtrPolyNode;
struct PolyNode //polygon: 多角形,多边形
{
int coff; //cofficient:系数,共同作用的;
int exp; //exponent : 指数;
PtrPolyNode next;
};
typedef PtrPolyNode Polynomial; //polynomial : 多项式
Polynomial ReadPoly();
Polynomial PolyAdd(Polynomial P1,Polynomial P2);
Polynomial PolyMult(Polynomial P1,Polynomial P2);
void PrintPoly(Polynomial P);
int main()
{
Polynomial P1=ReadPoly();
// PrintPoly(P1);
Polynomial P2=ReadPoly();
// PrintPoly(P2);
Polynomial Pm=PolyMult(P1,P2);
PrintPoly(Pm);
printf("tiaoshi\n");
PrintPoly(P1);
PrintPoly(P2);
Polynomial Pa=PolyAdd(P1,P2);
PrintPoly(Pa);
printf("tiaoshi\n");
PrintPoly(P1);
PrintPoly(P2);
return 0;
}
Polynomial ReadPoly()
{
Polynomial p=(Polynomial) malloc(sizeof(PolyNode));
p->next=NULL;
Polynomial Rear=p;
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode)); //必须要为新节点申请空间
int c,e;
scanf("%d%d",&c,&e);
temp->coff=c,temp->exp=e;
temp->next=NULL;
Rear->next=temp;
Rear=temp;
}
Polynomial temp=p; //删除头结点
p=p->next;
free(temp);
return p;
}
Polynomial PolyAdd(Polynomial P1,Polynomial P2)
{
Polynomial p=(Polynomial) malloc(sizeof(PolyNode));
p->next=NULL;
Polynomial Rear=p;
Polynomial t1=P1,t2=P2;
while(t1&&t2)
{
if(t1->exp>t2->exp)
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode));//只要需要记录数据,都要重新申请结点
temp->coff=t1->coff,temp->exp=t1->exp; //既然申请了新节点,那么就赋值便可,不要将原结点直接赋值给temp
Rear->next=temp;
Rear=Rear->next;
t1=t1->next;
}
else if(t1->exp<t2->exp)
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode));
temp->coff=t2->coff,temp->exp=t2->exp;
Rear->next=temp;
Rear=Rear->next;
t2=t2->next;
}
else
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode));
temp->coff=t1->coff+t2->coff,temp->exp=t1->exp;
if(temp->coff==0)
free(temp);
else
{
Rear->next=temp;
Rear=Rear->next;
}
t1=t1->next;
t2=t2->next;
}
}
while(t1) //接下来可以直接运用原链表的值
{
Rear->next=t1;
Rear=Rear->next;
t1=t1->next;
}
while(t2) //接下来可以直接运用原链表的值
{
Rear->next=t2;
Rear=Rear->next;
t2=t2->next;
}
Polynomial temp=p; //删除头结点
p=p->next;
free(temp);
return p;
}
Polynomial PolyMult(Polynomial P1,Polynomial P2)
{
Polynomial p=(Polynomial) malloc(sizeof(PolyNode));
p->next=NULL;
Polynomial Rear=p;
Polynomial t1=P1,t2=P2;
while(t1) //先用第二个链表的第一个结点与第一个链表的所有节点相乘
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode));
temp->coff=t1->coff*t2->coff;
temp->exp=t1->exp+t2->exp;
Rear->next=temp;
Rear=Rear->next;
t1=t1->next;
}
t2=t2->next;
while(t2) //接下来将第二个链表的所有节点与第一个链表的所有结点各自相乘,再相加
{
t1=P1;
Rear=p->next; //每次循环都将Rear指向头结点,即最大指数处
while(t1)
{
Polynomial temp=(Polynomial) malloc(sizeof(PolyNode));
temp->coff=t1->coff*t2->coff;
temp->exp=t1->exp+t2->exp;
temp->next=NULL;
while(Rear->next&&Rear->next->exp>temp->exp)
Rear=Rear->next;
if(Rear->next&&Rear->next->exp==temp->exp) //如果指数相同
{
if(Rear->next->coff+temp->coff) //如果系数相加不等于0,则加上系数
Rear->next->coff+=temp->coff;
else //否则删除这个系数为0的结点
{
Polynomial th=Rear->next;
Rear->next=th->next;
free(th);
}
free(temp);
}
else // 只要系数不相等,不管Rear->next 是否为NULL,都可以合并为下面这个代码
{
temp->next=Rear->next;
Rear->next=temp;
}
// else if(Rear->next) //下面两个if语句是把 Rear->next 是否为NULL分开讨论
// {
// temp->next=Rear->next;
// Rear->next=temp;
// }
// else
// Rear->next=temp;
t1=t1->next;
}
t2=t2->next;
}
Polynomial temp=p; //删除头结点
p=p->next;
free(temp);
return p;
}
void PrintPoly(Polynomial P)
{
if(!P)
printf("0 0\n");
else
{
int flag=0;
while(P)
{
if(flag)
printf(" ");
else
flag=1;
printf("%d %d",P->coff,P->exp);
P=P->next;
}
printf("\n");
}
}
解法二:用pair解决:
* 按指数降幂进行输入与输出,那么可以将多项式的每一项用pair来存储,其first存储指数,
* 其second存储系数,因为pair默认按first从小到大排序,如果first相同,再按second从小
* 到大排序;
/**
* 按指数降幂进行输入与输出,那么可以将多项式的每一项用pair来存储,其first存储指数,
* 其second存储系数,因为pair默认按first从小到大排序,如果first相同,再按second从小
* 到大排序;
*/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int maxn = 1e6+10;
PII t[maxn];
PII res[maxn];
void print(PII * s,int idx)
{
int flag = 1;
for(int i = idx-1;i>=0 ;--i)
{
if(res[i].second != 0)
{
if(flag)
flag = 0;
else
cout << ' ';
cout << res[i].second << ' ' << res[i].first;
}
}
if(flag) //如果是0多项式,输出(0 0);
puts("0 0");
else
puts("");
}
int main()
{
int n ,m;
cin >> n;
PII t1[n];
for(int i=0;i<n;++i)
cin >> t1[i].second >> t1[i].first;
cin >> m;
PII t2[m];
for(int i=0;i<m;++i)
cin >> t2[i].second >> t2[i].first;
int index = 0;
for(auto x:t1)
for(auto y:t2)
{
int a = x.second*y.second;
int p = x.first+y.first;
t[index] = {p,a};
++index;
}
sort(t,t+index);
int sum = 0, pre = 0;
int idx = 0;
for(int i = 0;i<index;++i)
{
if(i == 0 || pre == t[i].first)
{
sum += t[i].second;
pre = t[i].first;
}
else
{
res[idx] = {pre,sum};
++idx;
sum = t[i].second;
pre = t[i].first;
}
if(i == index-1 )
{
res[idx] = {pre,sum};
++idx;
}
}
print(res,idx);
index = 0;
int i=0 , j=0;
while(i<n && j<m)
{
if(t1[i].first < t2[j].first)
{
res[index] = t2[j];
index++;
j++;
}
else if(t1[i].first > t2[j].first)
{
res[index] = t1[i];
index++;
i++;
}
else if(t1[i].first == t2[j].first)
{
res[index].first = t1[i].first;
res[index].second = t1[i].second + t2[j].second;
++index;
++i;
++j;
}
}
while(i<n)
{
res[index] = t1[i];
++index;
++i;
}
while(j<m)
{
res[index] = t2[j];
++index;
++j;
}
sort(res,res+index); //将系数从小到大排序;
print(res,index);
return 0;
}