02-线性结构2 一元多项式的乘法与加法运算 (20分)

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

注意的是零多项式应输出0 0,因此输出的时候要判断指针指向的是否为零多项式,如果是就要输出0 0。

还有结尾不能有空格,即当指针域为不为NULL时输出空格,为NULL时不输出空格。

输入样例:

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

测试点:

测试点 结果 得分/满分 用时(ms) 内存(MB) 要点提示
测试点1 答案正确 12/12 2 1 sample换个数字
测试点2 答案正确 4/4 2 1 同类项合并时有抵消
测试点3 答案正确 2/2 2 1 系数和指数取上限,结果有零多项式
测试点4 答案正确 2/2 2 1 输入有零多项式和常数多项式
数递降方式输出乘积多项

思路:

详细的思路在课件2.4小白专场都有讲过,原以为听过就能会写,但是现实却是双手放在键盘上敲不出来,最后只能是照着PDF课件抄。我想还是代码量不够,还是要多加练习。
一共需要五个函数,分别负责读入数字(ReadPoly)、在现有链表的后面添加链表(Attach)、链表相加(Add)、链表相乘(Mult)和输出(PrintPoly)。

Attach是整个程序中最基本的函数,其他的函数基本都有调用。Attch就是新申请一个Polynomial类型的指针,把传入的数据域参数传到该指针指向的区域,然后再让传入的指针指向这块区域。

Add是链表相加的函数。申请一个Polynomial类型的指针P,两个指针分别指向P1、P2链表。指针域的expon大的就Attach到P,该指针移向下一个链表。若expon相等,就要判断coef是否为相反数。若未相反数,两个指针后移;若非则coef相加,expon不变,Attach到P上。

Mult是链表相乘的函数。首先判断P1和P2是否为空,有一个空就返回NULL。若都不为空,则用逐项插入的思想解决问题。首先让P1的第一项乘以P2,得到一条初始结果多项式P。接着,让剩下的P1各项和P2相乘,得到的多项式和P中的对比expon大小,比指针指向的expon大的就插入,小的就指针后移。

PrintPoly是输出函数。首先判断P是否为0多项式,若是则返回0 0,不是则顺着链表依次输出。当指向的链表的指针域不为NULL,输出空格。


#include <stdlib.h> 
#include <stdio.h>








struct PolyNode{
		int coef;//系数 
		int expon;//指数
		struct PolyNode * link; 
	};
typedef struct PolyNode * Polynomial;


void Attach(int c,int e,Polynomial * pRear)
{//在传入的链表后面再加一个链表 
	Polynomial temp;
	temp=(Polynomial)malloc(sizeof(PolyNode));
	temp->coef=c;
	temp->expon=e;
	temp->link=(*pRear)->link;
	(*pRear)->link=temp;
	(*pRear)=temp;
}
Polynomial ReadPoly()	//输入数字,转化为链表 
{
	Polynomial P,Rear,first;
	int N,c,e;
	
	P=(Polynomial)malloc(sizeof(PolyNode));	//申请头结点
	P->link=NULL;
	Rear=P;
	scanf("%d",&N);
	
	while(N--)
	{
		scanf("%d %d",&c,&e);
		Attach(c,e,&Rear);
	}
	
	first=P;	//三行代码,free掉头结点
	P=P->link;
	free(first);
	return P;
}


Polynomial Add(Polynomial P1,Polynomial P2)	//两个链表的相加 
{
	Polynomial temp,temp1,temp2,P;
	temp1=P1;
	temp2=P2;
	P=(Polynomial)malloc(sizeof(PolyNode));
	P->link=NULL;
	temp=P;
	while(temp1&&temp2)	//当两个链表都不为NULL时才要做下面的循环和判断。
	{
		if(temp1->expon>temp2->expon)
		{
			Attach(temp1->coef,temp1->expon,&temp);
			temp1=temp1->link;
		}else if(temp1->expon<temp2->expon){
			Attach(temp2->coef,temp2->expon,&temp);
			temp2=temp2->link;
		}else{		//两个多项式的expon相等时
			if(!(temp1->coef+temp2->coef)==0)
			{
		        Attach(temp1->coef+temp2->coef,temp1->expon,&temp);				
				temp1=temp1->link;
				temp2=temp2->link;
			}else{		//expon相等,coef互为相反数
				temp1=temp1->link;
				temp2=temp2->link;
			}
		}
	}
	for(;temp1;temp1=temp1->link)		//当有一个指针指向NULL时,说明这条多项式已经加完了。此时只要把另一条多项式剩下的全Attach到P后边就行了
	{
		Attach(temp1->coef,temp1->expon,&temp);
	}
	for(;temp2;temp2=temp2->link)
	{
		Attach(temp2->coef,temp2->expon,&temp);
	}
	temp=P;
	P=P->link;
	free(temp);
	return P;	
}
Polynomial Mult(Polynomial P1,Polynomial P2)	//两个链表的相乘 
{
	Polynomial P,Rear,t1,t2,t;
	int c,e;
	
	if(!P1||!P2)return NULL;	//判断两个多项式都不为零多项式
	
	t1=P1;
	t2=P2;
	P=(Polynomial)malloc(sizeof(PolyNode));
	P->link=NULL;
	Rear=P;
	while(t2)		//初始多项式由P1的第一项乘以P2的每一项得到
	{
		Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
		t2=t2->link;
    	}
    t1=t1->link;		//t1指针指向P1的第二项
	while(t1)		
	{
		t2=P2;
		Rear=P;	//每一次的t1指向的多项式乘以t2的每一项后,Rear都重新指回P的头结点,以便下一次得到的t1和t2的乘积插入P
		while(t2)
		{
			c=t1->coef*t2->coef;
			e=t1->expon+t2->expon;
			while(Rear->link&&Rear->link->expon>e)	//当Rear的下一项不为空且下一项的指数比当前的乘积e大时,Rear后移
			{									//为什么e不对比Rear指向的当前项的指数?
				Rear=Rear->link;					//因为是单链表,如果把当前的多项式插入Rear,那么当先多项式无法和上一项相连接
			}
			if(Rear->link&&Rear->link->expon==e)	//指数相等的情况
			{
				if(Rear->link->coef+c)				//系数相加不为零
				{
					Rear->link->coef+=c;
				}else{							//系数相加为0,是零多项式
					Rear->link->coef=0;
					Rear->link->expon=0;
				}
			}else{								//当前多项式的指数大于Rear的下一项指数
				t=(Polynomial)malloc(sizeof(PolyNode));
				t->coef=c;
				t->expon=e;
				t->link=Rear->link;
				Rear->link=t;
				Rear=Rear->link;
			}			
			t2=t2->link;
		}		
		t1=t1->link;
	}	
	Rear=P;
	P=P->link;
	free(Rear);
	return P;
}
void PrintPoly(Polynomial P)	//把链表以数字的形式输出
{ 
	if(!P)
	{
		printf("0 0");
	}
	while(P)
	{
		printf("%d %d",P->coef,P->expon);
		P=P->link;
		if(!P==NULL)		//只有在指针域不为NULL时,才输出空格间隔开每个多项式。即在多项式末位没有空格
		{
			printf(" ");
		}
	}
	printf("\n");
}




int main(){




	Polynomial P1,P2,PP,PS;
	P1=ReadPoly();
	P2=ReadPoly();
	PP=Mult(P1,P2);
	PrintPoly(PP);
	PS=Add(P1,P2);
	PrintPoly(PS);
	
	
}


  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值