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

https://pintia.cn/problem-sets/434/problems/5865

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

时间限制:200 ms
内存限制:64 MB

输入格式:
输入分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

首先,我们能确定这道题要用线性存储结构。线性存储结构分为顺序表和链表,注意到题目要求指数递降输出,即要求排序,顺序表的插入

多项式加法

题目给出的输入已经按照降幂顺序排列好,相加时不需要考虑顺序的问题,同时加法也不需要考虑同类项合并,但加法需要考虑系数互为相反数的项相加为0的情况。

运算方法:
开始之前,l1,l2分别指向两个多项式的第一项

  • 当l1的指数 > l2的指数时,复制l1的项到结果多项式,l1往后移动,l2不动
  • 当l1的指数 < l2的指数时,复制l2的项到结果多项式,l2往后移动,l1不动
  • 当l1的指数 = l2的指数时,若l1和l2的系数相加不为0,则复制到结果多项式,为0舍弃。完成操作后l1和l2都要向后移动

l1和l2只要有一个走到了表尾,就将它们当中没有走完的那个表的后续部分接到结果多项式,如果两者都走完了直接离开。

如果给出的输入,所以项全部抵消了,或本身给出的输入就是零多项式,此时结果多项式为空表,输出0 0

多项式乘法

乘法不用考虑相乘系数为0的情况,但乘法需要考虑顺序和同类项合并的问题。

运算方法:
用一个二重循环来实现,开始之前,l1,l2分别指向两个多项式的第一项

  1. 创建一个新的结果结点p
  2. p的系数 = l1的系数 × l2的系数
    p的指数 = l1的指数 + l2的指数
  3. 从结果多项式开头按顺序查找,找到第一个小于等于自己系数的项
  • 若小于,则改变指针域,将p插入链表
  • 若等于,结果多项式和p系数相加,同类项合并,销毁p

特别注意,结果多项式也是链表,如果已经销毁了p,应该设置continue语句,防止free之后的指针值接到链表

如果输入中有零多项式,全部项相乘都为0,此时结果多项式为空表,输出0 0


#include <stdio.h>
#include <stdlib.h> typedef struct _node{
int coef;
int expo;
struct _node *next;
}linkList; void
initList( linkList **l ); void
createList( linkList *l ); void
mulList( linkList *l1, linkList *l2 ); void
addList( linkList *l1, linkList *l2 ); int
main( int argc, char **argv )
{
linkList *l1, *l2;
initList( &l1 );
createList( l1 );
initList( &l2 );
createList( l2 );
mulList( l1, l2 );
addList( l1, l2 );
return 0;
} void
initList( linkList **l )
{
( *l ) = ( linkList* )malloc( sizeof( linkList ) );
( *l )->next = NULL;
} void
createList( linkList *l )
{
int n;
linkList *tail, *p;
tail = l;
scanf("%d", &n); while( n-- > 0 ){
p = ( linkList* )malloc( sizeof( linkList ) );
scanf("%d%d", &p->coef, &p->expo);
tail->next = p;
tail = p;
}
tail->next = NULL;
} void
mulList( linkList *l1, linkList *l2 )
{
linkList *p1, *p2;
linkList *result, *pre, *p;
initList( &result ); for( p1 = l1->next; p1 != NULL; p1 = p1->next ){
for( p2 = l2->next; p2 != NULL; p2 = p2->next ){
p = ( linkList* )malloc( sizeof( linkList ) );
p->coef = p1->coef * p2->coef;
p->expo = p1->expo + p2->expo; pre = result;
while( pre->next != NULL && pre->next->expo > p->expo ){
/*
** 遍历result, 找到插入的位置
*/
pre = pre->next;
} if( pre->next == NULL || pre->next->expo != p->expo ){
/*
** pre->next为NULL时, 元素值为最小, 插在最后作为表尾
** 先判断pre->next是否为NULL可以防止后面的判断语句出现对空指针解引用的错误
*/
p->next = pre->next;
pre->next = p;
}else{
/*
** 如果pre->next->expo等于p->expo, 两者为同类型, 合并
*/
pre->next->coef += p->coef;
free( p );
}
}
} if( result->next != NULL ){
/*
** 若结果为零多项式, 此时result为空表
*/
for( p1 = result->next; p1 != NULL; p1 = p2 ){
if( p1->coef != 0 ){
printf("%d %d", p1->coef, p1->expo );
if( p1->next != NULL ){
printf(" ");
}
}
p2 = p1->next;
free( p1 );
}
}else{
printf("0 0");
}
free( result );
printf("\n");
} void
addList( linkList *l1, linkList *l2 )
{
linkList *result, *p, *tail;
initList( &result );
tail = result; l1 = l1->next;
l2 = l2->next;
while( l1 != NULL && l2 != NULL ){
p = ( linkList* )malloc( sizeof( linkList ) );
if( l1->expo == l2->expo ){
if( l1->coef + l2->coef ){
p->coef = l1->coef + l2->coef;
p->expo = l1->expo;
}else{
free( p );
l1 = l1->next;
l2 = l2->next;
continue;
/*
** 如果没有continue, free之后的p会接在表尾
*/
}
l1 = l1->next;
l2 = l2->next;
}else if( l1->expo > l2->expo ){
p->coef = l1->coef;
p->expo = l1->expo;
l1 = l1->next;
}else{
p->coef = l2->coef;
p->expo = l2->expo;
l2 = l2->next;
}
if( l1 != NULL || l2 != NULL ){
tail->next = p;
tail = p;
}
} while( l1 != NULL && l2 == NULL ){
/*
** 两个都要判断, 避免在两者都为空指针时对空指针解引用
*/
p = ( linkList* )malloc( sizeof( linkList ) );
p->coef = l1->coef;
p->expo = l1->expo;
l1 = l1->next;
tail->next = p;
tail = p;
} while( l2 != NULL && l1 == NULL ){
p = ( linkList* )malloc( sizeof( linkList ) );
p->coef = l2->coef;
p->expo = l2->expo;
l2 = l2->next;
tail->next = p;
tail = p;
}
tail->next = NULL; if( result->next != NULL ){
for( p = result->next; p != NULL; p = tail ){
printf("%d %d", p->coef, p->expo);
if( p->next != NULL ){
printf(" ");
}
tail = p->next;
free( p );
}
}else{
printf("0 0");
}
}

PTA数据结构 习题3.6 一元多项式的乘法与加法运算 (20分)的更多相关文章

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

    原题地址 https://pta.patest.cn/pta/test/15/exam/4/question/710 5-2 一元多项式的乘法与加法运算   (20分) 设计函数分别求两个一元多项式的 ...

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

    设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. ...

  3. 线性结构2 一元多项式的乘法与加法运算 【STL】

    02-线性结构2 一元多项式的乘法与加法运算(20 分) 设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和 ...

  4. 线性结构CT 02-线性结构1 一元多项式的乘法与加法运算

    设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. ...

  5. 浙江大学PAT上机题解析之3-04. 一元多项式的乘法与加法运算

    设计函数分别求两个一元多项式的乘积与和. 输入格式说明: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分 ...

  6. 3-04. 一元多项式的乘法与加法运算(20)(ZJU_PAT 结构体)

    题目链接:http://pat.zju.edu.cn/contests/ds/3-04 设计函数分别求两个一元多项式的乘积与和. 输入格式说明: 输入分2行.每行分别先给出多项式非零项的个数.再以指数 ...

  7. 一元多项式的乘法与加法运算 【STL-map哈希-map反向迭代器遍历 + 零多项式】

    设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. ...

  8. 一元多项式的乘法与加法运算(C语言)

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

  9. PTA数据结构与算法题目集(中文) 7-37 模拟EXCEL排序 (25 分)

    PTA数据结构与算法题目集(中文)  7-37 模拟EXCEL排序 (25 分) 7-37 模拟EXCEL排序 (25 分)   Excel可以对一组纪录按任意指定列排序.现请编写程序实现类似功能. ...

随机推荐

  1. Caffe 快速入门笔记

    官网:http://caffe.berkeleyvision.org/ 其中包含Notebook Example方便入门学习 只是使用她的库还是比较简单,其难点在于: 安装 源码 训练好的模型,用于迁 ...

  2. docker开启remote-api 2375端口后,Failed to start Docker Application Container Engine,重启docker失败的问题解决

    1.  按照网上的教程修改了 /usr/lib/systemd/system/docerk.service配置后,重启失败.修改/etc/docker/daemon.json 增加hosts后重启也是 ...

  3. Java 学习:对象和类

    对象和类 从认识的角度考虑是先有对象后有类.对象,是具体的事物.类,是抽象的,是对对象的抽象. 从代码运行角度考虑是先有类后又对象.类是对象的模板. 对象:对象是类的一个实例,有状态和行为. 类:类是 ...

  4. Python 高级特性(3)- 列表生成式

    range() 函数 日常工作中,range() 应该非常熟悉了,它可以生成一个迭代对象,然后可以使用 list() 将它转成一个 list # 判断是不是迭代对象 print(isinstance( ...

  5. 枚举类enum

    一.枚举类 package com.xxx.xf.common.enums; import com.xxx.xf.workday.contant.HolidayContant; /** * @Auth ...

  6. Fastjson反序列化漏洞基础

    Fastjson反序列化漏洞基础 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象. 0x0 ...

  7. [第二篇]——Docker 架构之Spring Cloud直播商城 b2b2c电子商务技术总结

    Docker 架构 Docker 包括三个基本概念: 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统.比如官方镜像 ubuntu:16.04 就包含了完整的一 ...

  8. go build 与go install

    相同点都能生成可执行文件 不同点go build 不能生成包文件, go install 可以生成包文件go build 生成可执行文件在当前目录下, go install 生成可执行文件在bin目录 ...

  9. 【Sass/SCSS 完整自学中文版教程02】SCSS 官方英文文档翻译整理

    Sass 调试 目录 Sass 调试 @error @warn @debug 如果对本文有任何问题,建议,或者在前端技术体系方面有任何问题,可以添加我的微信: drylint , 我会尽可能为你解答, ...

  10. CTFd+ubuntu service搭建等待更新

    CTFd是一款基于Apache2.0的协议的开源CTF平台,最新版本目前为1.20.该平台功能强大,基本上能够满足目前的CTF竞赛需求,同时,该平台提供了强大的插件功能,可以自己进行插件开发实现自己的 ...