DSOJ Addition of Polynomial(多项式求和)

题目链接

#include<stdio.h>		//多项式的加法
#include<stdlib.h>		//多项式本身可能不是最简的情况,即需要合并多项式幂指数相同的项

typedef struct node
{
	int coef;	//系数coefficient
	int expn;	//指数exponent
	struct node *next;
}Node;

Node *insert(Node *head, Node *p)	//插入函数
{
	Node *p1, *p2;
	if (head->next == NULL)
	{
		head->next = p;
		p->next = NULL;
		return head;
	}
	else
	{
		p1 = p2 = head->next;
		while (p->expn < p1->expn&&p1->next != NULL)
		{
			p2 = p1;
			p1 = p1->next;
		}
		if (p->expn >= p1->expn)
		{
			p->next = p1;
			if (p1 == head->next)
				head->next = p;
			else
				p2->next = p;
		}
		else
		{
			p1->next = p;
			p->next = NULL;
		}
	}
	return head;
}

Node *create()		//创建按照幂指数升序排列的带头链表
{
	Node *head, *p;
	int coef, expn;
	head = (Node *)malloc(sizeof(Node));
	head->next = NULL;
	scanf("%d %d", &coef, &expn);
	while (expn >= 0)
	{
		p = (Node *)malloc(sizeof(Node));
		p->coef = coef;
		p->expn = expn;
		head = insert(head, p);
		scanf("%d %d", &coef, &expn);
	}
	return head;
}

Node *ADD(Node *A, Node *B)		//多项式相加(幂指数降序)
{
	Node *pa1, *pa2, *pb, *p;
	pa1 = A->next;
	pa2 = A;			//pa2指向pa1的前驱
	pb = B->next;
	while (pa1&&pb)
	{
		if (pb->expn < pa1->expn)		//将A的当前节点后移即可
		{
			pa2 = pa1;
			pa1 = pa1->next;
		}
		else
			if (pb->expn > pa1->expn)	//插入在pa1之前
			{
				p = pb->next;
				pb->next = pa1;
				pa2->next = pb;
				pa2 = pb;
				pb = p;
			}
			else              //幂指数相等
			{						
				pa1->coef = pa1->coef + pb->coef;		//先相加,之后再删除系数为0的项
				pa2 = pa1;
				pa1 = pa1->next;
				pb = pb->next;
			}
	}
	if (pb)
		pa2->next = pb;
	return A;
}

void simplify(Node *head)		//将多项式化为最简,即合并同指数幂项
{
	Node *p1, *p2, *p;
	p2 = head->next;
	if (!p2) return;
	p1 = p2->next;
	while (p1)
	{
		if (p2->expn == p1->expn)
		{
			p2->coef = p2->coef + p1->coef;
			p = p1;
			p1 = p1->next;
			p2->next = p1;
			free(p);
		}
		else
		{
			p2 = p1;
			p1 = p1->next;
		}
	}
}

void delzero(Node *head)		//删除coef为零的节点
{
	Node *p1, *p2, *p;
	p2 = head;
	p1 = head->next;
	while (p1)
	{
		if (p1->coef == 0)
		{
			p = p1;
			if (p1 == head->next)
				head->next = p1->next;
			else
				p2->next = p1->next;
			p1 = p1->next;
			free(p);
		}
		else
		{
			p2 = p1;
			p1 = p1->next;
		}
	}
}

void show(Node *A)
{
	Node *p;
	p = A->next;
	while (p)
	{
		printf("[ %d %d ] ", p->coef, p->expn);
		p = p->next;
	}
	printf("\n");
}

int main()
{
	Node *A[100], *B[100];
	int i, n;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		A[i] = create(); 
		B[i] = create();
		A[i] = ADD(A[i], B[i]);
	}
	for (i = 0; i < n; i++)
	{
		simplify(A[i]);
		delzero(A[i]);
		show(A[i]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值