7-2 一元多项式的乘法与加法运算 (20 分)
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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
代码如下:
#include<iostream>
using namespace std;
typedef struct chain_list* list;
struct chain_list {
int base;
int exponent;
list next;
};
list create(){ //创建节点函数
list ptr=(list)malloc(sizeof(struct chain_list));
ptr->base=ptr->exponent=0;
ptr->next=NULL;
return ptr;
}
void attach(int b,int e,list* ptr) { //在末尾添加节点函数
list temp=(list)malloc(sizeof(struct chain_list));
temp->base=b;
temp->exponent=e;
(*ptr)->next=temp;
temp->next=NULL;
(*ptr)=temp;//使(*ptr)指向最后一个节点
//注意形参使用的是list* ptr,才能改变ptr的指向,若形参为list ptr则该语句将无效
}
list read() { //读取函数
int n;
cin >> n;
if (n==0) return NULL;//空字符立即返回null
list temp_ptr=create();//创建空节点
list ptr=temp_ptr;
int b,e;
while(n--) {
cin >> b >> e;
attach(b,e,&temp_ptr);
}
list t=ptr;
ptr=ptr->next;
free(t);//清除空节点
return ptr;
}
int print(list p) { //输出函数
if (!p) { //若为空字符输出"0 0",立即返回
cout<<"0 0";
return 0;
}
int flag=0;
while(p) {
if (p->base!=0) {
flag++; //判断" "的输出
if (flag==1) cout<<p->base<<" "<<p->exponent;
else cout<<" "<<p->base<<" "<<p->exponent;
while (p->next!=NULL&&p->next->base==0)
p=p->next;
//由于在加法和乘法计算时未清除底数为0的节点,故在此用while跳过这些节点
}
p=p->next;
}
if (flag==0) cout<<"0 0"; //对应p中全为底数为0的节点时的情况
return 0;
}
list add(list p1,list p2) { //加法函数
list p=create();//创建空节点
list temp=p;
while(p1&&p2) { //比较p1,p2
if (p1->exponent>p2->exponent) { //p1大则计入p1,p1向后移一个节点,以下类推
attach(p1->base,p1->exponent,&p);
p1=p1->next;
} else if(p1->exponent==p2->exponent) {
attach(p1->base+p2->base,p2->exponent,&p);
p1=p1->next;
p2=p2->next;
} else {
attach(p2->base,p2->exponent,&p);
p2=p2->next;
}
}
while(p1) { //计入p1剩余的
attach(p1->base,p1->exponent,&p);
p1=p1->next;
}
while(p2) { //计入p2剩余的
attach(p2->base,p2->exponent,&p);
p2=p2->next;
}
list t=temp;
temp=temp->next;
free(t);//去除空节点(头结点)
return temp;
}
list multi(list p1,list p2) { //乘法函数
if (!p1||!p2) return NULL;//有一个为空则返回null
list p=create();
list t1=p1,t2=p2;
list first=p;
while(t2) { // 1.用t1第一项乘t2每一项
attach(t1->base*t2->base,t1->exponent+t2->exponent,&p);
t2=t2->next;
}
t1=t1->next;//t1向后移一个节点
list temp=NULL;
while (t1) { // 2.用t1的第二项到最后一项分别乘t2的每一项,插入第1步的链表中
t2 = p2;
temp = first;
while (t2) {
int b = t1->base*t2->base;//乘的结果
int e = t1->exponent + t2->exponent;
//找到插入的位置,这个地方需要特别注意
while (temp->next&&temp->next->exponent > e)
temp = temp->next;
/*该while中的判断顺序一定是temp->next在前,
否则当temp->next为空时,temp->next->exponent会使程序异常终止*/
if (temp->next==NULL) attach(b,e,&p);//此情况在末尾添加节点
else {
if (temp->next->exponent == e) //合并同类项
temp->next->base += b;
else { //在链表中插入节点
list t = (list)malloc(sizeof(struct chain_list));
t->base = b;
t->exponent = e;
t->next = temp->next;
temp->next = t;
}
}
t2 = t2->next;
}
t1 = t1->next;
}
temp = first;
first = first->next;
free(temp);
return first;
}
int main() {
list p1,p2,p;
p1=p2=p=NULL;
p1=read();
p2=read();
p=multi(p1,p2);
print(p);
cout<<endl;
p=add(p1,p2);
print(p);
}