PTA 习题3.6 一元多项式的乘法与加法运算

2023-11-04

题目

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

输入格式:
输入分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。
甚至一开始算加法多项式时,我将list1和list2的节点直接插入到结果多项式中,破坏了链表的结构,导致求乘法多项式一直得不到想要的数据。
刷提前理清思路真的很重要,以后再也不会一上来就直接写代码了。

1、加法多项式

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

运算思路:
分别令pq指向list1list2(即两个多项式)的第一项数据
当p的指数大于q的指数,将节点p复制给新节点newNode,将newNode移动到result的末尾,p往后移动,q不动
p的指数小于q的指数,将节点q复制给新节点newNode,将newNode移动到result的末尾,q往后移动,p不动
p的指数等于q的指数,若pq的系数相加不为0,则复制到结果多项式,为0则舍弃。之后pq都要向后移动
如果pq还有剩余的节点,直接接到结果多项式的末尾
如果给出的输入,所以项全部抵消了,或本身给出的输入就是零多项式,此时结果多项式为空表,输出0 0

在这里插入图片描述

2、乘法多项式

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

用二重循环得到多项式相乘的所有结果
将每个结果节点newNode插入到结果多项式中合适的位置(按照指数降序排列)

  1. 先找到正确的插入位置,从结果多项式开头按顺序查找,找到第一个小于等于自己系数的项
  2. 如果小于,直接插入
  3. 如果等于,则要合并同类项,要记得判断合并后的系数是否为0,是则删除这个项

在这里插入图片描述
动图来源

代码

#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
    int coefficient; //系数
    int exponent;    //指数
    struct Node *next;
} Node, *LinkList;

void initList(LinkList *head)
{
    if ((*head = (LinkList)malloc(sizeof(Node))) == NULL)
        exit(-1);
    (*head)->next = NULL;
}
void creatList(LinkList head)
{
    LinkList p, tail = head;
    int count;
    scanf("%d", &count);
    while (count-- > 0)
    {
        p = (LinkList)malloc(sizeof(Node));
        scanf("%d%d", &p->coefficient, &p->exponent);
        tail->next = p;
        tail = p;
    }
    tail->next = NULL;
}
void printList(LinkList head)
{
    LinkList p = head->next;
    while (p)
    {
        if (p == head->next)
            printf("%d %d", p->coefficient, p->exponent);
        else
            printf(" %d %d", p->coefficient, p->exponent);
        p = p->next;
    }
}

void addition(LinkList list1, LinkList list2)
{
    LinkList result, p = list1->next, q = list2->next, tail, newNode;
    initList(&result);
    tail = result;
    while (p && q)
    {
        int coefficient1, coefficient2, exponent1, exponent2;
        newNode = (LinkList)malloc(sizeof(Node));

        // 当p的指数大于q的指数,将节点p复制给newNode,将newNode移动到result的末尾,p往后移动,q不动
        if (p->exponent > q->exponent)
        {
            newNode->coefficient = p->coefficient;
            newNode->exponent = p->exponent;
            newNode->next = NULL;
            tail->next = newNode;
            tail = newNode;
            p = p->next;
        }
        else if (p->exponent < q->exponent)
        {
            // 当p的指数小于q的指数,将节点q复制给newNode,将newNode移动到result的末尾,q往后移动,p不动
            newNode->coefficient = q->coefficient;
            newNode->exponent = q->exponent;
            newNode->next = NULL;
            tail->next = newNode;
            tail = newNode;
            q = q->next;
        }
        else
        {
            // 当p和q的指数相等,直接将两个的系数相加。如果相加后的系数为0,则将p,q直接移动到下一位
            if (p->coefficient + q->coefficient == 0)
            {
                p = p->next;
                q = q->next;
                free(newNode);
            }
            else
            {
                newNode->coefficient = p->coefficient + q->coefficient;
                newNode->exponent = p->exponent;
                newNode->next = NULL;
                tail->next = newNode;
                tail = newNode;
                p = p->next;
                q = q->next;
            }
        }
    }
    // 如果p或q还有剩余节点,直接接到result的末尾
    if (!p)
    {
        tail->next = q;
    }
    if (!q)
    {
        tail->next = p;
    }

    if (!result->next)
    {
        free(result);
        printf("0 0");
    }
    else
    {
        printList(result);
    }
}

void multiplication(LinkList list1, LinkList list2)
{
    LinkList result, p = list1->next, q , tail, newNode;
    initList(&result);
    tail = result;
    while (p)
    {
        q = list2->next;
        while (q)
        {
            // 创建新建的newNode
            newNode = (LinkList)malloc(sizeof(Node));
            newNode->coefficient = p->coefficient * q->coefficient;
            newNode->exponent = p->exponent + q->exponent;
            newNode->next = NULL;

            LinkList temp = result;
            // 找到合适的插入位置
            while (temp->next && newNode->exponent < temp->next->exponent)
            {
                temp = temp->next;
            }
            // 插入或者合并同类项
            if (temp->next == NULL || newNode->exponent > temp->next->exponent)
            {
                newNode->next = temp->next;
                temp->next = newNode;
            }
            else if (newNode->exponent == temp->next->exponent)
            {
                temp->next->coefficient += newNode->coefficient;
                // 如果合并同类项后系数为0,得删除这个节点
                if(!temp->next->coefficient){
                    LinkList deleteNode=temp->next;
                    temp->next=deleteNode->next;
                    free(deleteNode);
                }
                free(newNode);
            }
            q = q->next;
        }
        p = p->next;
    }
    if (!result->next)
    {
        free(result);
        printf("0 0");
    }
    else
    {
        printList(result);
    }
}
int main()
{
    LinkList list1, list2;
    initList(&list1);
    initList(&list2);
    creatList(list1);
    creatList(list2);
    multiplication(list1, list2);
    printf("\n");  
    addition(list1, list2);
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PTA 习题3.6 一元多项式的乘法与加法运算 的相关文章

随机推荐

  • MYSQL常见查询-SELECT

    1 查看某一产品销量城市排行榜前10名 并展示其同环比 思路 取出今日 昨日 上周该商品的销量 通过开窗函数计算同环比 代码 SELECT FROM SELECT n FIRST VALUE n num OVER PARTITION by
  • Ubuntu:vim键盘上下左右按键变ABCD

    原因 ubuntu自带vi不完整导致 解决方法一 sudo apt get remove vim common sudo apt get install vim 解决方法二 sudo apt get install vim gtk
  • 在Mac上配置Vue开发环境

    因为Vue是NodeJS的模块 要想使用Vue需要先安装NodeJS 在Mac中安装NodeJS通过brew包管理器就会很方便 因为访问源速度问题建议使用5 阿里 Homebrew开源项目地址 https gitee com cunkai
  • 抱抱脸(hugging face)教程-中文翻译-分享一个模型

    分享一个模型 最后两个教程展示了如何使用 PyTorch Keras 和 Accelerate 优化分布式设置的模型 下一步就是把你的模型公之于众 我们相信公开分享知识和资源 使人工智能大众化 我们鼓励你考虑与社区分享你的模式 以帮助其他人
  • 史上最全!Selenium 录制脚本+八种元素定位方式+具体代码演示

    话不多说 先附上练习的所有代码链接 link 文章目录 引言 什么是自动化测试 一 selenium定义 二 使用selenium IDE录制脚本 三 元素的定位方式 1 id gt find element by id 2 name gt
  • 欧拉筛法代码及数学原理

    数学原理 首先 从 2 开始 把 2 的倍数都标记为合数 然后把下一个未标记的数 3 标记为素数 再把 3 的倍数标记为合数 接着把下一个未标记的数 5 标记为素数 再把 5 的倍数标记为合数 以此类推 直到标记到 N 为止 在标记的过程中
  • Java #{} 和 ${} 的含义及区别

    表示一个占位符 向占位符输入参数 MyBatis 会自动进行 Java 类型和 jdbc 类型的转换 且不需要考虑参数的类型 以预编译的方式传入 可以有效的防止 SQL 注入 提高系统安全性 例如 传入字符串 MyBatis 最终拼接好的
  • 学会了c语言怎么编程,三天学会C语言编程

    本文试图通过上中下三篇文章引领大家进入C语言的世界 C语言是一个非常古老 1972年发明 的语言了 想必大家都有所了解 没有了解也没关系 C语言以难学和难以使用着称 想用好C语言更是难上加难 本文不假设读者有任何其它编程语言的基础 但需要了
  • 安装或卸载Anaconda后Windows自带的cmd命令行窗口会闪退

    问题现象 Anaconda初次安装或者重装后 如果打开Windows系统自带的cmd命令窗口 会马上闪退 Win R 输入cmd就闪退 Win R 输入cmd d可以正常打开 解决方案 网上很多给出的解决方案是 按Win R 输入reged
  • Invalid configuration `x86_64-unknown-linux-gnu': machine

    checking host system type Invalid configuration x86 64 unknown linux gnu machine x86 64 unknown not recognized 在做 config
  • Gamemaker studio2经验(4)——打字机效果

    问题概述 在很多游戏中 算了实在不好意思写引言了 就直说啦 如果你是UT粉 想用gm搞搞UT的同人作品但是又无从下手 那么请看过来 对于RPG类游戏 文字交流系统是不可或缺的 但是gm的文字系统 实在有些一言难尽 那没办法 谁让gm是真爱呢
  • 本地计算机架设http服务器,Http File Server(简易Http服务器服务端)

    如果您感觉配置IIS和apache等web服务端太麻烦的话 不妨试试Http File Server Http File Server是一套简易的Http服务器服务端系统 它无需安装 运行后简单配置一下就可以开放80端口了 与传统Web服务
  • iframe嵌入本地视频或者http链接视频禁止自动播放

    本地视频禁止自动播放 http链接视频禁止自动播放 在视频链接后加上 autoplay 0即可
  • windows连网疑问

    如果我的笔记本连接一台无线AP 当我不更改SSID 而只去更改密码的时候 为什么会连不上 当我把电脑里关于这个AP的连接信息删掉之后 就能够连接上了 所以 是跟之前保存的信息有关系的 但其中的作用原理不是很清楚 不过 我想 这必定是wind
  • ubuntu16.04下teamviewer启动不显示界面

    导读 在Ubuntu下使用teamviewer的时候 通过命令行输入 teamviewer 不会出现界面 就像这样 没有显示teamviewer的界面 adminuser adminuser pc teamviewer Init Check
  • linux 系统调用

    5 1 5 如何使用系统调用 如图5 2所示 用户应用可以通过两种方式使用系统调用 第一种方式是通过C库函数 包括系统调用在C库中的封装函数和其他普通函数 图5 2 使用系统调用的两种方式 第二种方式是使用 syscall宏 2 6 18版
  • VUE路由的hash模式与history模式的区别

    hash模式url带 号 history模式不带 号 通过history api 我们丢掉了丑陋的 但是它也有个问题 不怕前进 不怕后退 就怕刷新 f5 如果后端没有准备的话 因为刷新是实实在在地去请求服务器的 不玩虚的 在hash模式下
  • 使用fio测试磁盘I/O性能

    测试准备 工具 fio Flexible IO Tester 官方网站 http freecode com projects fio http brick kernel dk snaps 注意 性能测试建议直接通过写裸盘的方式进行测试 会得
  • JavaScript之js对象终极序列化(可序列化函数)

    案例官方地址 http www rainx org 2017 01 04 javascript js E5 AF B9 E8 B1 A1 E7 BB 88 E6 9E 81 E5 BA 8F E5 88 97 E5 8C 96 你是否遇到了
  • PTA 习题3.6 一元多项式的乘法与加法运算

    文章目录 题目 1 加法多项式 2 乘法多项式 代码 题目 设计函数分别求两个一元多项式的乘积与和 输入格式 输入分2行 每行分别先给出多项式非零项的个数 再以指数递降方式输入一个多项式非零项系数和指数 绝对值均为不超过1000的整数 数字