(浙大陈越版)数据结构 第二章 线性结构 2.4 多项式的加法和乘法运算实现

news2024/9/21 22:20:29

目录

2.4.1多项式的加法运算实现

如何设计一个函数分别求两个一元多项式的和?

算法思路:两个指针p1,p2分别指向两个多项式的第一个结点(最高项)并循环

循环:

2.4.2 多项式的乘积

1.多项式的表示

2.程序框架搭建

3.如何读入多项式

4.加法实现

5.乘法实现

6.多项式输出


2.4.1多项式的加法运算实现

注:这里的多项式只局限于一元多项式

如何设计一个函数分别求两个一元多项式的和?

观察多项式求和的过程规律,对于次数不同的项我们直接放到最终结果中即可,对于次数相同的项才进行加减运算。于是我们可以用一个不带头结点的单向链表,按照指数递减的顺序来排列每一项,来实现多项式加法。

算法思路:两个指针p1,p2分别指向两个多项式的第一个结点(最高项)并循环

循环:

  • p1指数=p2指数:二者系数做相加,若结果不为0则添加到结果多项式中,p1和p2都向后挪一项
  • p1指数>p2指数:p1当前项添加到结果多项式,p1指向下一项
  • p1指数<p2指数:p2当前项添加到结果多项式,p2指向下一项

当其中一个多项式已经处理完毕,就将另一个多项式的所有节点全部添加到结果多项式中。

struct PolyNode{
    int coef;//系数
    int expon;//指数
    struct PolyNode *link;//指向下一个结点的指针
};
typedef struct PolyNode *Polynomial;
Polynomial p1,p2;
//c代表系数,e代表指数,pRear代表此时最后一个结点的指针位置(二级指针)
void Attach(int c,int e,Polynomial *pRear)
{
    Polynomial P;
    
    P = (Polynomial)malloc(sizeof(struct PolyNode));
    
    //新结点赋值
    P->coef = c;
    P->expon = e;
    P->link = NULL;
    
    //将P插入到pRear之后
    (*pRear)->link = P;
    *pRear = P;
}

 

加法的大体框架:三个循环,一个比较t1和t2,两个分别测试多项式是否为空。

Polynomial PolyAdd(Polynomial p1,Polynomial p2)
{
    int sum;
    
    //定义结果多项式的头、尾、临时头结点
    Polynomial front,rear,temp;
    rear = (Polynomial)malloc(sizeof(struct PolyNode));
    front = rear;

    while(p1&p2){
        switch(Compare(p1->expon,p2->expon)){
            case 1://说明p1指数更高
                
                //添加结果,把现在的系数和指数接到结果多项式尾后
                Attach(p1->coef,p1->expon,&rear);

                p1 = p1->link;//后移
                break;
            case -1://p2指数更高
                Attach(p2->coef,p2->expon,&rear);//添加结果
                p2 = p2->link;//后移
                break;
            case 0:
                sum = p1->coef + p2->coef;
                if(sum){//如果系数和不为0的话,sum为计算后系数
                    Attach(sum,p1->expon,&rear);
                }
                p1 = p1->link;
                p2 = p2->link;
                break;
        }
    }

    //把没处理完的另一个多项式的所有节点遍历复制到结果多项式里
    
    //处理p1(p1不空)
    for(;p1;p1 = p1->link){
        Attach(p1->coef,p1->expon,&rear);
    }
    for(;p2;p2 = p2->link){
        Attach(p2->coef,p2->expon,&rear);
    }
    
    //rear指向结果多项式最后一项,由于全部处理完毕,用不到了
    rear->link = NULL;
    
    //为了释放temp,将其赋给fornt,fornt向后挪
    temp = front;
    front = front->link;//fornt指向结果多项式第一个非0项
    free(temp);//释放临时头结点
    return front;
}

2.4.2 多项式的乘积

多项式的乘积,需要用一个多项式的每一项和另一个多项式的每一项相乘,具体来说需要每项系数相乘、指数相加,然后将乘积加在一起得出结果。与加法类似的,指数相同的项,其系数需要合并。

若以以下格式规定输入和输出样例:

项数 第一项系数 第一项指数 第二项系数 ...

并在输出中分别列出

  • 多项式相乘的结果
  • 多项式相加的结果

这个问题可以细分为若干个小问题:

  1. 如何表示多项式
  2. 如何搭建程序框架
  3. 如何读入多项式
  4. 加法实现
  5. 乘法实现
  6. 多项式输出

1.多项式的表示

最佳策略:仅表示非零项

用于实现的数据类型:

数组链表
优点代码简单,调试容易动态性强
缺点需要事先确定数组大小(可用动态数组解决)代码复杂,调试困难

2.程序框架搭建

3.如何读入多项式

4.加法实现

加法的具体实现前文已经提过

5.乘法实现

方法1:把乘法运算转换为加法运算。

        先把p1第一项乘以p2每一项,再把第二项乘以p2每一项...最后相加到结果多项式里

方法2:逐项插入。(本次程序使用)

        也就是把p1第一项乘以p2第一项,插入到结果多项式。再用p1第一项乘以p2第二项,插入结果多项式...此算法关键是寻找插入位置。结果多项式的初步形式可以用p1第一项乘以p2每一项。

6.多项式输出

以下还是用链表来实现(为了易读而分开了)

//设计多项式数据结构
typedef struct PolyNode *Polynomial;
struct PolyNode{
    int coef;
    int expon;
    Polynomial link;
};
//插入项
void Attach(int c,int e,Polynomial *pRear){
    Polynomial p;
    p = (Polynomial)malloc(sizeof(struct PolyNode));
    p->coef = c;
    p->expon = e;
    p->link = NULL;
    (*pRear)->link = p;
    *pRear = p;
    //让rear结点一开始指向链表头,这样之后插入的多项式都在其之后
}
//读入多项式
PolyNomial ReadPoly(){
    PolyNomial p,Rear,temp;
    int c,e,N;

    scanf("%d",&N);
    //创建链表头空结点
    p = (PolyNomial)malloc(sizeof(struct PolyNode));
    p->link = NULL;
    Rear = p;

    while(N--){
        scanf("%d %d",&c,&e);
        Attach(c,e,&Rear);
    }
    
    t = p; p = p->link; free(t);//删除临时头结点

    return p;
}
//相乘
Polynomial Mult(Polynomial p1,Polynomial p2){
    Polynomial p, Rear, t1, t2, t;
    int c,e;

    //判断p1p2是否为空
    if(!p1 || p2)
        {return NULL;}

    //为了循环计算,需要创建临时变量
    t1 = p1;t2 = p2;
    p = (Polynomial)malloc(sizeof(struct PolyNode));
    p->link = NULL;
    Rear = p;

    //p1第一项乘以p2每一项
    while(t2){
        Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
        t2 = t2->link;//向后挪一项
    }
    t1 = t1->link;
    while(t1){
        t2 = p2;
        Rear = p;

        while(t2){
            e = t1->expon + t2->expon;
            c = t1->coef * t2->coef;

            //已有有序序列,将新值按序插入
            //比较Rear指向的下一个结点指数与当前要插入结点的指数
            while((Rear->link && Rear->link->expon) > e)
            {Rear = Rear->link;}

            //若Rear下一项指数=要插入项指数
            if((Rear->link && Rear->link->expon) == e){
                if(Rear->link->coef + c)
                    //则不需要申请结点,让系数相加就行
                    {Rear->link->coef += c;}
                

                //如相加后=0就删掉
                else{
                    t = Rear->link;
                    Rear->link = t->link;
                    free(t);
                }
            }else{//需要申请新结点
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef = c;t->expon = e;
                t->link = Rear->link;
                Rear->link = t;Rear = Rear->link;
                t2 = t2->link;
            }
            t1 = t1->link;
        }//while(t1)结束
        t2 = p; p = p->link;free(t2);//删除空结点

        return p;
    }
}
//输出多项式
void PrintPoly(Polynomial p){
    int flag = 0;//调整输出格式的变量

    if(!p){
        printf("0 0\n");
        return;
    }
    
    while(p){
        if(!flag)//第一项,flag为0不输出
            flag = 1;
        else//非第一项,flag为1输出一个空格
            printf(" ");
        printf("%d %d",p->coef,p->expon);
        p = p->link;
    }
    printf("\n");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/511165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IPsec VPN IKE方式协商密钥

实验拓扑 要求pc1与pc2两个网络访问走ipsec隧道互访。 前言&#xff1a; ipsecs 隧道两端的acl规则定义的协议类型要一致&#xff0c;如果一端是ip协议&#xff0c;另一端也必须是ip协议 配置acl的原因是&#xff1a;1&#xff0c;通过acl&#xff08;permit&#xff09;指定需…

Metalama released Crack

Metalama released Crack Metalama是一个面向C#的元编程框架。它可以帮助您提高代码质量和生产力。使用Metalama&#xff0c;您可以通过在编译过程中动态生成样板文件来减少样板文件。您的源代码仍然非常清晰。根据体系结构、模式和约定实时验证代码。无需等待代码评审。通过定…

React从入门到实战 - React初体验

文章目录 特点相关JS库步骤准备步骤操作步骤 关于虚拟DOMJSX语法规则函数式组件常见的几种错误正确写法 类式组件 特点 采用组件化模式&#xff0c;声明式编程&#xff0c;提高开发效率及组件复用率在React Native 中使用React语法进行移动端开发使用虚拟DOM优秀的Diffing算法…

Java8 map.getOrDefault()你真的了解吗

大家好&#xff0c;我是三叔&#xff0c;很高兴这期又和大家见面了&#xff0c;一个奋斗在互联网的打工人。 map.getOrDefault()方法 在Java编程中&#xff0c;Map是一种非常常用的数据结构。Map通常用于存储键值对&#xff0c;其中每个键映射到一个值。当我们尝试访问一个不…

文件一直处于修改状态 git checkout 无法还原的问题解决方法

问题描述 最近在 RT-Thread 时&#xff0c;使用 Git 回退版本验证问题&#xff0c;后来 git pull 拉取最新代码后&#xff0c;发现里面有几个文件&#xff0c;一直为【修改】状态&#xff0c;并且无法还原&#xff0c;git checkout xxx git reset --hard 都用了&#xff0c;依旧…

基于AT89C51单片机的温度控制系统报警器

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87771724?spm1001.2014.3001.5503 源码获取 单片机读取温度传感器当前的温度值并在LCD液晶显示屏上的第一行显示当前的温度值&#xff0c;单片机读取按键状态并通过…

Flask框架之异常处理、请求钩子、上下文的使用

Flask框架之异常处理、请求钩子、上下文的使用 异常处理捕获指定异常状态码捕获指定异常类型抛出HTTP Exception 请求钩子概述基本使用 请求上下文概述应用上下文current_app对象g对象 请求上下文request对象session对象 异常处理 捕获指定异常状态码 可以使用app.errorhandle…

Github的使用

1.基本概念&#xff1a; 仓库&#xff08;Repository&#xff09;:仓库用来存放项目代码&#xff0c;每个项目对应一个仓库&#xff0c;多个开源项目则有多个仓库 收藏&#xff08;Star&#xff09;:收藏项目&#xff0c;方便下次查看 复制克隆项目:&#xff08;Fork&#x…

JVM类加载、类变量初始化顺序

题目 先来看一个题目&#xff0c;以下程序的输出结果是什么 运行结果 关于类加载机制 关于JVM的类加载 《深入理解Java虚拟机》中关于类加载是这样说的&#xff1a; Java虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#x…

【SLAM学习】基于Pangolin绘制运动轨迹

Pangolin是一个轻量级的跨平台视图控制库&#xff0c;主要用于可视化、交互和调试三维数据。该库提供了一系列图形界面工具&#xff0c;包括窗口、OpenGL渲染器、3D相机、图像显示等&#xff0c;可以方便地进行三维数据可视化和交互。 Pangolin库的主要特点如下&#xff1a; 轻…

SpringBoot的多配置文件

文章目录 1.配置文件的命名规则2.配置文件选择3.配置文件的优先级 1.配置文件的命名规则 配置文件一般要求以application开头&#xff0c;可以是.yml结尾的文件&#xff0c;也可以是.properties结尾的文件。 2.配置文件选择 当有多个配置文件&#xff0c;需要指定其中一个生…

关于C语言取余运算的那些大坑

0.前言 您好&#xff0c;这里是limou3434的一篇个人博文&#xff0c;感兴趣的话您也可以看看我的其他文章&#xff0c;本次我想给您带来的是关于C语言操作符‘%’的一些奇怪现象以及背后的原理解释&#xff0c;本章用了一点点python语法&#xff08;比如在python中“//”是整除…

C++开发环境的搭建-Windows:VSCode+mingw64+CMake

文章目录 一、软件安装1. 网址及下载的软件2. VSCode中配置关于C的最简插件&#xff1a; 二、C调试环境的编译要求1. 在编译时要带-g参数2. 多文件编译需要分步编译 三、VSCode的调试配置如下&#xff1a;1. 单文件调试设置4. 多文件调试设置 一、软件安装 1. 网址及下载的软件…

【JavaEE进阶】——第六节.第一个MyBatis程序

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;JavaEE进阶 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录 前…

计算机视觉(5)—— 图像分类

目录 五、图像分类 5.1 AlexNet 5.2 VGG 5.3 GoogLeNet、Inception 5.3.1 Inception V1 5.3.2 Inception V2 5.3.3 Inception V3 5.3.4 Inception V4 5.4 ResNet 残差网络 5.4.1 ResNet 5.4.2 ResNeXt 5.5 CNN设计准则 五、图像分类 5.1 AlexNet 5.2 VGG 5.3 Go…

【剑指 Offer】05,替换字符创中的空格;难度等级:简单。易错点:C++中 char 和 string 类型的转换

【剑指 Offer】05&#xff0c;替换字符创中的空格&#xff1b;难度等级&#xff1a;简单。 文章目录 一、题目二、题目背景三、我的解答四、易错点五、知识点&#xff1a;char 和 string 类型的转换 一、题目 二、题目背景 在网络编程中&#xff0c;如果 URL 参数中含有特殊字…

消息推送平台的实时数仓?!flink消费kafka消息入到hive

大家好&#xff0c;3y啊。好些天没更新了&#xff0c;并没有偷懒&#xff0c;只不过一直在安装环境&#xff0c;差点都想放弃了。 上一次比较大的更新是做了austin的预览地址&#xff0c;把企业微信的应用和机器人消息各种的消息类型和功能给完善了。上一篇文章也提到了&#…

windows安装Anaconda

Anacond是什么&#xff1f; 和Python有啥关系&#xff1f; 1、Anacond 是一个python的发行版&#xff0c;包括了python和很多常见的软件库, 和一个包管理器conda。常见的科学计算类的库都包含在里面了&#xff0c;使得安装比常规python安装要容易。 2、Anaconda是专注于数据分…

分布式系统概念和设计——时间和全局状态(分布式系统中的时间问题)

分布式系统概念和设计 时间和全局状态 全局物理时间的缺乏使我们很难查明分布式程序的执行时状态。 我们经常需要知道当进程B处在某种状态依赖进程是什么状态&#xff0c;但不能通过依靠物理时钟理解一个同一个时刻到底是什么情况。 维护分布数据一致性算法检查发送给服务器的…

数学(三) -- LC[1010][1015] 可被 K 整除的最小整数

1 可被 K 整除的最小整数 1.1 题目描述 题目链接&#xff1a;https://leetcode.cn/problems/smallest-integer-divisible-by-k/description/ 1.2 思路分析 模运算 如果让你计算 1234 ⋅ 6789 1234 \cdot 6789 1234⋅6789 的个位数&#xff0c;你会如何计算&#xff1f; 由于…