多项式

多项式加法和乘法

#include<bits/stdc++.h>
typedef struct node* ptr;
struct node{
	int ex;
	int coef;
	ptr next;
};//用链表存多项式
ptr p1,p2;
ptr read(void)//读入多项式
{
	ptr p;
	int n;
	scanf("%d",&n);
	p=(ptr)malloc(sizeof(struct node));
	p->next=NULL;//生成头节点
	ptr ans=p;
	for(int i=0;i<n;i++){
		ptr tmp=(ptr)malloc(sizeof(struct node));//循环读入 不断申请
		scanf("%d",&(tmp->coef));
		scanf("%d",&(tmp->ex)); 
		tmp->next=NULL;
		p->next=tmp;
		p=p->next;
	}
	return ans;//返回头节点 相当于不存东西的a[0]
}
void print(ptr p){
	int flag=0;
	if(p->next==NULL)
	{
		printf("0 0\n");
		return;
	}//零多项式特判
	else{
		p=p->next;
		while(p)
	{
		if(!flag){
			printf("%d %d",p->coef,p->ex);
			flag=1;
			p=p->next;
		}
		else{
			printf(" %d %d",p->coef,p->ex);
			p=p->next;
		}
		
	}
	}
	printf("\n");
}///打印链表

ptr add(ptr p1,ptr p2)//多项式加法
{
	ptr p,pp1=p1->next,pp2=p2->next;//传进来的P1、p2都是头节点,不能改动传进来的指针,定义两个指针分别指向存数据的结构(多项式的头)
	p=(ptr)malloc(sizeof(struct node));
	p->next=NULL;
	ptr ans=p;//用p把结果串起来,p是移动的,用ans存p的头以便返回
	while(pp1&&pp2){
		if(pp1->ex>pp2->ex){
			p->next=pp1;
			p=p->next;
			pp1=pp1->next;
		}
		else if(pp1->ex<pp2->ex){
			p->next=pp2;
			p=p->next;
			pp2=pp2->next;
		}
		else{
			ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->next=NULL;
			tmp->coef=pp1->coef+pp2->coef;
			tmp->ex=pp1->ex;
			if(tmp->coef){
				p->next=tmp;
				p=p->next;
			}//如果系数加成了0 就删除这个节点
			pp1=pp1->next;
			pp2=pp2->next;
		}
	}
	if(pp1)p->next=pp1;
	if(pp2)p->next=pp2;//接好剩下的项
	return ans; 
}
ptr muti(ptr p1,ptr p2)//多项式乘法
{
	if(p1->next==NULL)return p1;
	if(p2->next==NULL)return p2;///特判 如果是零多项式 直接返回零多项式 多亏了找到的第四组测试点 如果对一个空指针NULL取东西,就会出现段错误
	ptr t1=p1->next,t2=p2->next,t2head=t2;//t2head是p2指向的多项式的首项
	ptr p=(ptr)malloc(sizeof(struct node));
	ptr phead=p;
	while(t2){
		ptr tmp=(ptr)malloc(sizeof(struct node));
		tmp->coef=t1->coef*t2->coef;
			tmp->ex=t1->ex+t2->ex;
			tmp->next=NULL;
			p->next=tmp;
			p=p->next;	
			t2=t2->next;	
	}//这一步很妙 先生成第一组的结果 后面的结果就可以插入到第一组的链表中 
	t1=t1->next;
	while(t1)
	{
		t2=t2head;
		while(t2)
		{
			p=phead;
			ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->coef=t1->coef*t2->coef;
			tmp->ex=t1->ex+t2->ex;
			tmp->next=NULL;
			while(p->next&&tmp->ex<p->next->ex)
   			   p=p->next;//要按指数递降的顺序输出 只要系数小就往后移动
            if(p->next!=NULL&&tmp->ex==p->next->ex){
            	tmp->coef+=p->next->coef;
				if(tmp->coef){
					tmp->next=p->next->next;
				//	ptr pp=p->next;
					p->next=tmp;
				//	free(pp);
					
				}
				else{
				//	ptr pp;
				//	pp=p->next;
					p->next=p->next->next;//系数是0就不插入了
				//	free(pp);
				}
			}
			else{
				 tmp->next=p->next;
				// ptr pp=p->next;
				 p->next=tmp;
				 //free(pp);
			}	
			t2=t2->next;
		}

		t1=t1->next;
	}
	return phead;
}
int main()
{
	ptr p1,p2;
	p1=read();
	p2=read();
	print(muti(p1,p2));
	print(add(p1,p2));
	return 0;
}
	

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值