2021-03-14

7-2 一元多项式的乘法与加法运算

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

输入格式:
输入分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 <stdio.h>
#include <stdlib.h>
struct node{
	int num1;
	int num2;
	struct node *Next;
};
typedef struct node *List;
List Make(int m);
void print(struct node * head);
List connectc(struct node *, struct node *, int, int);
List connectj(struct node *, struct node *, int, int);
List traverse(struct node *);
int main(void)
{
	int n1, n2;
	List p1, p2, L1, p3, p4, L2;
	scanf("%d",&n1);
	p1 = p3 = Make(n1);
	scanf("%d",&n2);
	p2 = p4 = Make(n2);
//	print(p1);
	putchar('\n');
	if(n1 == 0 && n2 == 0){  /*当并不输入任何数时输出的结果*/ 
	printf("%d %d\n%d %d",0, 0, 0, 0);
	}else{
		if(n1 == 0 && n2 != 0){  /*用于判断connectc()函数,有向乘的时候次数为零*/ 
			printf("%d %d\n",0, 0);
			print(p2);
		}else if(n1!=0&&n2!=0){
	L1 = connectc(p1, p2, n1, n2);
	L1 = traverse(L1);
	print(L1);	
	putchar('\n');
		}
	if(n1 != 0 && n2 == 0){/*用于判断connectj()函数,有向加后的时候系数为零*/ 
		printf("%d %d\n",0,0);
		print(p1);		
	}else if(n1!=0 &&n2!=0){
	L2 = connectj(p3, p4, n1, n2);
	L2 = traverse(L2);
	print(L2);	
	}
	}
	return 0;
 } 
List Make(int m)
{
	List p, head, tail;
	int n1, n2, i;
	head = tail = NULL;	
	for(i = 0; i < m; i++){	
	scanf("%d%d",&n1, &n2);
	p = (struct node *)malloc(sizeof(struct node));	
	p->num1 = n1;
	p->num2 = n2;
	p->Next = NULL;
    if(head == NULL)head = p;
    else tail->Next = p;
    tail = p;	
	}

	return head;	
}
void print(struct node * head)
{
   	List p;
   	int flot = 1;
   	p = head;
   	if(head->num1 == 0 || head->num2 == 0){ /*当为零多项式时直接输出*/ 
   		printf("%d %d", 0, 0);
	   }else{	   
   	while(p){
   		if(flot==1){
   			if(p->num1 != 0) /*用于合并同类项时当系数为零就直接不输出了*/ 
   			printf("%d %d",p->num1, p->num2);
		   }else{
   	        if(p->num1 != 0)
   			printf(" %d %d",p->num1, p->num2);
		   }
   		p = p->Next;
   		flot = 0;
	   }
    }
}
List connectc(struct node *p1, struct node *p2, int n1, int n2)
{
	int i, j;
	List p, head, ptr, ptr1 = p1, ptr2 = p2;
	head = (struct node *)malloc(sizeof(struct node));
	head = p = NULL;
	for(i = 0; i < n2; i++){
		for(j = 0; j < n1; j++){			
		ptr = (struct node *)malloc(sizeof(struct node));
				ptr->num1 = ptr1->num1 * ptr2->num1;
				ptr->num2 = ptr1->num2 + ptr2->num2;
				ptr->Next = NULL;				
		        if(head == NULL)head = ptr;
		        else p->Next = ptr;										
			p = ptr;
			ptr1 = ptr1->Next;
			}
		ptr1 = p1;
		ptr2 = ptr2->Next;
	}

	return head;
}
List traverse(struct node *L)
{
	List p1, p2, tail = NULL;
	for(p1 = L; p1; p1 = p1->Next){
		for(p2 = p1->Next, tail = p1; p2;){
			if(p1->num2 == p2->num2){
				p1->num1 = p1->num1 + p2->num1;
				tail->Next = p2->Next;
				free(p2);
				p2 = tail->Next;/*p2再指向下一个节点*/ 
			}else{
				tail = p2;
				p2 = p2->Next;
			}
			
		}
		
	}
		return L;
}
List connectj(struct node *p3, struct node *p4, int n1, int n2)
{
	int i, j, flot = 1;
	List head, p, ptr1, ptr2 ,ptr, ptr3;
	head = (struct node *)malloc(sizeof(struct node));
	head = p = NULL;
	while(p3&&p4){	
	ptr = (struct node *)malloc(sizeof(struct node));
		if(p3->num2 > p4->num2){
			ptr->num1 = p3->num1;
			ptr->num2 = p3->num2;
			if(head == NULL)head = ptr;
			else p->Next = ptr;
			p = ptr;
			p3 = p3->Next;
		}else if(p3->num2 < p4->num2){
			ptr->num1 = p4->num1;
			ptr->num2 = p4->num2;
			if(head == NULL)head = ptr;
			else p->Next = ptr;							
			p = ptr;
			p4 = p4->Next;
		}else{
			if(head == NULL){
				ptr->num1 = p4->num1 + p3->num1;
				if(ptr->num1 == 0)ptr->num2 = 0; 
				else ptr->num2 = p4->num2;
				head = ptr;
			}else{
				ptr->num1 = p4->num1 + p3->num1;
				ptr->num2 = p4->num2;
				p->Next = ptr;
			}
			p = ptr;
			p3 = p3->Next;
			p4 = p4->Next;
		}
	}
	if(p3)p->Next = p3;
	if(p4)p->Next = p4;
	for(ptr3 = head; ptr3; ptr3 = ptr3->Next){
		if(ptr3->num1 != 0) /*组建的新链表是否为零多项式*/ 
		flot = 0;
	}
	if(flot == 1){  
		head->num1 = 0;
		head->num2 = 0;
		head->Next = NULL;
		return head;
	}		
	return head;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值