PTA 7-2 一元多项式的乘法与加法运算 (C语言实现)

2023-11-04

题目网址:https://pintia.cn/problem-sets/15/problems/710
题目描述:设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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

题目分析:这道题的关键不是算法,而是用来存储系数和指数的数据结构的选择。通常我们的第一反应是用数组,数组的第i个元素存储 x^i 这一项的系数,但是一旦遇到多项式乘法后,数组将会变成一个稀疏矩阵,加上项数的不确定性,可能会导致存储空间的不足,因此数组是很坏的一个选择。那么既具有灵活存储又能动态分配内存空间的ADT非链表莫属了。
算法解析:由于题目要求按照指数降序输出,因此为了方便链表元素前后搜索或置换,我采用了双向链表。

  1. 多项式加法:按照归并排序中归并的方法,定义一个头结点名为sum的链表存储加法结果,每次取两个多项式头部的元素进行比较,小的先进入sum链表,若相等则系数相加后进入链表。进入链表的元素所在的节点指针指向下一个直至NULL
  2. 多项式乘法:定义一个头结点名为mul的链表存储乘法结果。乘法的难点在于不能向加法那样顺序增添节点,这时每个节点的last和next指针就有用了。采用最笨拙的暴力搜索,使两个多项式一项一项分别相乘,将所乘得到的结果与mul尾结点比较,若尾结点指数大,则添加至新尾结点,若尾结点指数小,则用一个新的循环向前搜索,直至找到正确的位置,插入,若与尾结点指数相同,则系数相加即可。同时要注意各链表指针的变化。
  3. 输出:考虑到存在零多项式(项数为0或结果系数为0的情况),我统一在输出函数进行处理

AC代码:我的算法可能有些笨拙,如果有更好的算法,还请大佬们留言告知,谢谢

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

struct Node{
	struct Node* last;
	int cof;
	int exp;
	struct Node* next;
};
int m,n;

struct Node* Creat(int k);
struct Node* Print(struct Node* head);
struct Node* Sum(struct Node* head1, struct Node *head2);
struct Node* Mul(struct Node* head1, struct Node *head2);

int main()
{
	struct Node* head1, *head2;
	struct Node* sum, *mul;
	
	scanf("%d",&m);
	if (m!=0)
	{
		head1 = Creat(m);
	}
	else
	{
		head1 = (struct Node*)malloc(sizeof(struct Node));
		head1->cof = head1->exp = 0;
		head1->last = head1->next = NULL;
	}
	scanf("%d",&n);
	if (n!=0)
	{
		head2 = Creat(n);
	}
	else
	{
		head2 = (struct Node*)malloc(sizeof(struct Node));
		head2->cof = head2->exp = 0;
		head2->last = head2->next = NULL;
	}
	
	sum = Sum(head1, head2);
	mul = Mul(head1, head2);
	
	Print(mul);
	printf("\n");
	Print(sum);
} 

struct Node* Creat(int k)
{
	struct Node* head, *tail, *p;
	int i;
	for (i=0; i<k; i++)
	{
		p = (struct Node*)malloc(sizeof(struct Node));
		scanf("%d %d",&p->cof, &p->exp);
		if (i==0)
		{
			head = tail = p;
			tail->next = NULL;
			head->last = NULL;
		}
		else
		{
			tail->next = p;
			p->last = tail;
			tail = p;
			p->next = NULL;
		}
	}
	return head;
}

struct Node* Print(struct Node* head) //同时处理零多项式的情况
{
	int count = 0;
	if (head==NULL)
	{
		printf("0 0");
		return NULL;
	}
	while (head!=NULL)
	{
		if (head->cof==0) 
		{
			head = head->next;
			continue;
		}
		if (count==0)
		{
			printf("%d %d",head->cof,head->exp);
			count = 1;
		}
		else
		{
			printf(" %d %d",head->cof, head->exp);
		}
		head = head->next;
	}
	if (count==0) printf("0 0");
}

struct Node* Sum(struct Node* head1, struct Node *head2)
{
	struct Node*sum = NULL, *head = NULL, *tail = NULL;
	while (head1!=NULL && head2!=NULL)
	{
		sum = (struct Node*)malloc (sizeof(struct Node));
		if (head==NULL)
		{
			head = tail = sum;
			head->last = NULL;
			tail->next = NULL;
		}
		else
		{
			tail->next = sum;
			sum->last = tail;
			tail = sum;
			tail->next = NULL;
		}
		if (head1->exp==head2->exp)
		{
			sum->cof = head1->cof + head2->cof;
			sum->exp = head1->exp;
			head1 = head1->next;
			head2 = head2->next; 
		}
		else if(head1->exp > head2->exp)
		{
			sum->cof = head1->cof;
			sum->exp = head1->exp;
			head1 = head1->next;
		}
		else
		{
			sum->cof = head2->cof;
			sum->exp = head2->exp;
			head2 = head2->next;
		}
	}
	while (head1!=NULL)
	{
		sum = (struct Node*)malloc(sizeof(struct Node));
		tail->next = sum;
		sum->last = tail;
		tail = sum;
		tail->next = NULL;
		sum->cof = head1->cof;
		sum->exp = head1->exp;
		head1 = head1->next;
	}
	while (head2!=NULL)
	{
		sum = (struct Node*)malloc(sizeof(struct Node));
		tail->next = sum;
		sum->last = tail;
		tail = sum;
		tail->next = NULL;
		sum->cof = head2->cof;
		sum->exp = head2->exp;
		head2 = head2->next;
	}
	return head;
}

struct Node* Mul(struct Node* head1, struct Node *head2)
{
	struct Node* mul = NULL, *head = NULL, *tail = NULL, *find = NULL, *insert = NULL;
	struct Node* newhead = NULL;
	if (m==0||n==0)
	{
		return NULL;
	}
	while (head1!=NULL)
	{
		newhead = head2;//防止丢失原链表头结点
		while (newhead!=NULL)
		{
			mul = (struct Node*)malloc(sizeof(struct Node));
			if (head==NULL)
			{
				head = tail = mul;
				head->last = NULL;
				tail->next = NULL;
			}
			
			mul->cof = head1->cof * newhead->cof;
			mul->exp = head1->exp + newhead->exp;
			if (mul->exp < tail->exp)//如果所得结果小于mul的尾结点指数,则增添为新的尾结点
			{
				tail->next = mul;
				mul->last = tail;
				tail = mul;
				tail->next = NULL;
			}
			else 
			{
				find = tail;
				while (find->last!=NULL && mul->exp > find->exp)//想前搜索至正确位置
					find = find->last;
					if (mul->exp < find->exp)
					{
						insert = (struct Node*)malloc(sizeof(struct Node));
						insert->cof = mul->cof;
						insert->exp = mul->exp;
					
						//inserting
						find->next->last = insert;
						insert->last = find;
						insert->next = find->next;
						find->next = insert;
					
						mul = NULL;
					}
					else //mul->exp==find->exp
					{
						if (find->last!=NULL)
						find->cof += mul->cof;
						mul = NULL;
					}
			}
			newhead = newhead->next;
		}
		head1 = head1->next;
	}
	return head;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PTA 7-2 一元多项式的乘法与加法运算 (C语言实现) 的相关文章

  • 基于tensorflow搭建神经网络

    基于tensorflow搭建神经网络 一 tf keras搭建神经网络步骤 六步法 import train test model tf keras models Sequential model compile model fit mod
  • 大学计算机组成原理试题答案,重庆大学计算机组成原理试题集含部分答案.doc...

    计算机组成原理 试题集 一 选择题 在每小题列出的四个备选项中只有一个是符合题目要求的 请将其代码填写在题后的括号内 1 反映计算机基本功能的是 A 操作系统 B 系统软件 C 指令系统 D 数据库系统 2 若二进制数为1111 101 则
  • HBase Compaction 原理与线上调优实践

    作者 vivo 互联网存储技术团队 Hang Zhengbo 本文对 HBase Compaction 的原理 流程以及限流的策略进行了详细的介绍 列举了几个线上进行调优的案例 最后对 Compaction 的相关参数进行了总结 一 Com
  • 【Java】BF算法(串模式匹配算法)

    什么是BF算法 BF算法 即暴力算法 是普通的模式匹配算法 BF算法的思想就是将目标串S的第一个与模式串T的第一个字符串进行匹配 若相等 则继续比较S的第二个字符和T的第二个字符 若不相等 则比较S的第二个字符和T的第一个字符 依次比较下去
  • 【LeetCode】层数最深叶子节点的和(python)

    题目描述 给你一棵二叉树 请你返回层数最深的叶子节点的和 解题思路 深度搜索优先遍历二叉树 先找到叶子节点 然后求和 Definition for a binary tree node class TreeNode def init sel

随机推荐