数据结构题 3(一元多项式计算器)

题目:

                                                一元多项式运算器

(1)建立多项式。

(2)输出多项式。

(3) +,两个多项式相加,建立并输出和多项式。

(4) -,两个多项式相减,建立并输出差多项式。

扩展:

(5) *,多项式乘法。

(6) ( ),求多项式的值。

题解:

一元多项式运算器的计算中包含加减法,其中一元多项式说明有多个项所以我们可以考虑结构体数组或者链表来存储该数据元素,如果使用结构体数组来存储该数据元素进行计算的话,即要保存其项的个数和各项的系数和指数,在运算加减法时则需要使用多重循环来寻找指数相同的项来进行加减法。但是本篇博客主要简介使用的方法是链表来进行一元多项式的运算。

在创建链表时则需要考虑其链表中所要的值:指数、系数和指向下一个节点的指针。创建链表则需考虑如果输入的指数值相同则循环次数不加继续进行顺换里面的内容则需要使用的到结束语句continue。

结构体的内容如下所示:

typedef struct polynomial
{
    float Coef; //系数
    int Index;   //指数
    struct polynomial *next;
} polynomial;

在创建时需考虑是否可以写进链表的代码如下所示:

如果指数相同则不写入链表继续进行数据的输入。

while(cp->next && temp->Index > cp->next->Index)
        {
            cp = cp->next;    //找到链表结点的尾部,且指数是递增的
        }
        if(cp->next && temp->Index == cp->next->Index){     // 如果已经存在相同指数的多项式,跳出循环
            continue;
        }
        temp->next = cp->next;
        cp->next = temp;

若链表输入的数据比下一个数据的指数要小于或等于的时候则跳出while循环进入判断语句if,如果该数据的指数与下一结点的指数相等的时候continue退出不将数据保存在链表之中,若比下一个结点的指数要小的时候则保存在下一个结点之前的位置。

即如下图所示:

相同时则不加入该链表之中即可。

 链表创建成功之后我们就可以开始实现其功能,例如一元多项式的加减法,加法与减法的思路大致相同,在此只对一元多项式的加法进行讲述,加法则需要找到指数相同的项相关系数相加即可完成加法的相关操作。创建一个加法的函数,不返回值,使用二级指针指向链表的地址,直接对链表进行修改即可。

void AddPolyn(polynomial **pa, polynomial **pb);

 然后声明几个指针,其中两个指针分别指向链表的第一个数据,还有一个指针指向一个链表本身的头指针,然后声明一个循环当两个链表其中有一个空了之后退出该循环,首先判断指数的大小,因为我们创建的两个链表的指数都是升序排列的,在此将两个的链表最终和的结果存储在一个链表之中按照升序的方式排列,所以对两个链表的指数开始进行判断,如果指数小(且没有相同指数)的则首先进入结果链表之中,存入结果链表的指针向后移动一位再次与另一个指针指向的结点指数相比较,如果有相同的指数项存在则将其的指数相加然后存入结果链表之中,随后将指针都向后移动一个结点。然后当其中一个链表结束之后说明再也没有相同的指数出现因此我们可以把剩下的链表内容直接存储在结果链表之中。此加法的操作就结束了,一元多项式的减法操作与其相似只不过是把相同指数相加改为相减即可。

完成上面操作的代码如下所示:

void Add(polynomial **pa, polynomial **pb)
{
    polynomial *cpa, *cpb, *p = (*pa);
    cpa = (*pa)->next;
    cpb = (*pb)->next;
    while(cpa && cpb)       //对每一项进行比较
    {
        if(cpa->Index < cpb->Index)
        {
            p->next = cpa;
            p = cpa;
            cpa = cpa->next;
        }
        else if(cpa->Index > cpb->Index)
        {
            p->next = cpb;
            p = cpb;
            cpb = cpb->next;
        }
        else
        {
            if(cpa->Coef + cpb->Coef == 0)
            {
                cpa = cpa->next;
                cpb = cpb->next;

            }
            else
            {
                cpa->Coef += cpb->Coef;
                p->next = cpa;
                p = cpa;
                cpa = cpa->next;
                cpb = cpb->next;
            }
        }
    }
    if(cpa)
        p->next = cpa;
    else
        p->next = cpb;
    free(*pb);          //*pb已经为空,释放空间
}

但是减法与其不同的点在于如果减数的链表长度多余被减数的链表长度则不可以直接加入结果链表之中需要将其系数的符号进行改变再加入到结果链表之中。

该操作的代码如下所示:

    if(cpb){
        p->next = cpb;
        while(cpb){
            cpb->Coef *= -1; // 改变系数的符号,将减数多项式的系数变为负的
            cpb = cpb->next;
        }
    }

在一元多项式的乘法之中我们利用的函数与其加法函数相同都是使用二级指针,直接对链表本身进行修改,每一项与另一项进行相乘,所以我们才函数开头需创建两个指针,其中一个指针指向链表的头指针,保存链表内容。在乘法进行之前还需要将内容保存在一个函数之中,即将链表内容完全复制在另一个链表中,将此链表重新初始化。然后让此复制的链表与另一链表进行相乘结果保存在复制链表之中,再与之前的链表相加即可得到结果。

运行乘法的代码如下所示:

void Multiply(polynomial **pa, polynomial **pb)
{
    polynomial *cpa, *ccpa;
    cpa = *pa;                      //保存着原pa的内容
    CreatePolyn(pa, 0);         //从新初始化pa为头结点
    (*pb) = (*pb)->next;
    while(*pb)                      //只要*pb不为NULL一直进行
    {
        Copy(&ccpa, cpa);      //将后者复制给前者
        MultiplyOperate(ccpa, *pb); 
        Add(pa, &ccpa);        //将结果加入到pa中,直到得到最后的结果
        (*pb) = (*pb)->next;
    }

}

void Copy(polynomial **pa, polynomial *pb)
{
    Create(pa, 0);
    polynomial *temp, *cpa;
    cpa = *pa;
    pb = pb->next; // 移动指针指向第一个节点
    while(pb)
    {
        //进行复制操作
        temp = (polynomial *)malloc(sizeof(polynomial));
        temp->Coef = pb->Coef;
        temp->Index = pb->Index;
        temp->next = NULL;
        cpa->next = temp;
        cpa = temp;
        pb = pb->next;
    }
}

void MultiplyOperate(polynomial *pa, polynomial *pb)
{
    pa = pa->next;
    while(pa)
    {
        pa->Coef *= pb->Coef;
        pa->Index += pb->Index;
        pa = pa->next;
    }
}

乘法结束之后,该一元多项式运算器就到这里了。

下面附上该题的完整代码:

#include <iostream>
#include<stdlib.h>
using namespace std;

typedef struct polynomial
{
    float Coef; //系数
    int Index;   //指数
    struct polynomial *next;
} polynomial;

//功能函数声明
void CreatePolyn(polynomial **p, int m);
void Add(polynomial **pa, polynomial **pb);
void Subtract(polynomial **pa, polynomial **pb);
void Multiply(polynomial **pa, polynomial **pb);
void Copy(polynomial **pa, polynomial *pb);
void MultiplyOperate(polynomial *pa, polynomial *pb);
void Print(polynomial *p);

int main()
{

    polynomial *pa, *pb;    //定义两个结构体指针
    int n,m;                //用来存放多项式的项数
    int choose;             //选择加减乘
    int Flag = 1;
    while (1) {
        if (Flag == 1) {
            cout << "***************** 一元多项式计算器 *****************" << endl;
            cout << "请输入第一个多项式的项数->";
            cin >> n;
            CreatePolyn(&pa, n);
            cout << endl;
            cout << "请输入第二个多项式的项数->";
            cin >> m;
            CreatePolyn(&pb, m);
            cout << endl;


            cout << "********************************" << endl;
            cout << "本计算器可以进行的计算方式:" << endl;
            cout << "1.相加" << endl;
            cout << "2.相减" << endl;
            cout << "3.相乘" << endl;
            cout << "********************************" << endl;
            cout << endl;
            cout << "请选择计算方式:";
            cin >> choose;

            if (choose == 1) {
                Add(&pa, &pb);         //加法
            } else if (choose == 2) {
                Subtract(&pa, &pb);    //减法
            } else{
                Multiply(&pa, &pb);    //乘法
            } 

            cout << "结果如下: " << endl;
            Print(pa);
            cout << endl;
        } 
		else {

            cout << "**********************************" << endl;
            cout << "           谢谢使用本系统!            " << endl;
            cout << "**********************************" << endl;
            return 0;
        }

        cout << endl;
        cout << "**********************************" << endl;
        cout << "           是否继续使用?            " << endl;
        cout << "1.是" << endl;
        cout << "2.否" << endl;
        cout << "**********************************" << endl;
        cin >> Flag;
    }
}

void CreatePolyn(polynomial **p, int m)
{
    int i, data;
    polynomial *cp, *temp;
    (*p) = (polynomial *)malloc(sizeof(polynomial));
    (*p)->Coef = 0.0;
    (*p)->Index = -1;
    (*p)->next = NULL;
    for(i=1; i<=m; ++i){
        cp = *p;        //初始位置
        temp = (polynomial *)malloc(sizeof(polynomial));
        cout << "请输入第" << i << "项的系数: ";
        cin >> temp->Coef;
        cout << "请输入第" << i << "项的指数: ";
        cin >> temp->Index;

        while(cp->next && temp->Index > cp->next->Index)
        {
            cp = cp->next;
        }
        if(cp->next && temp->Index == cp->next->Index){     // 如果已经存在相同指数的多项式,跳出循环
            continue;
        }
        temp->next = cp->next;
        cp->next = temp;
    }
}

void Add(polynomial **pa, polynomial **pb)
{
    polynomial *cpa, *cpb, *p = (*pa);
    cpa = (*pa)->next;
    cpb = (*pb)->next;
    while(cpa && cpb)       //对每一项进行比较
    {
        if(cpa->Index < cpb->Index)
        {
            p->next = cpa;
            p = cpa;
            cpa = cpa->next;
        }
        else if(cpa->Index > cpb->Index)
        {
            p->next = cpb;
            p = cpb;
            cpb = cpb->next;
        }
        else
        {
            if(cpa->Coef + cpb->Coef == 0)
            {
                cpa = cpa->next;
                cpb = cpb->next;

            }
            else
            {
                cpa->Coef += cpb->Coef;
                p->next = cpa;
                p = cpa;
                cpa = cpa->next;
                cpb = cpb->next;
            }
        }
    }
    if(cpa)
        p->next = cpa;
    else
        p->next = cpb;
    free(*pb);          //*pb已经为空,释放空间
}

void Subtract(polynomial **pa, polynomial **pb)
{
    polynomial *cpa, *cpb, *p = (*pa);
    cpa = (*pa)->next;
    cpb = (*pb)->next;
    while(cpa && cpb)   //对每一项进行比较
    {
        if(cpa->Index < cpb->Index)
        {
            p->next = cpa;
            p = cpa;
            cpa = cpa->next;
        }
        else if(cpa->Index > cpb->Index)
        {
            p->next = cpb;
            p = cpb;
            p->Coef *= -1;  // 此时结果为负数,需改变符号
            cpb = cpb->next;
        }
        else                //  此时指数相等
        {
            if(cpa->Coef == cpb->Coef)  //如果两项系数相等,删除该节点
            {
                cpa = cpa->next;
                cpb = cpb->next;

            }
            else
            {
                cpa->Coef -= cpb->Coef;
                p->next = cpa;
                p = cpa;
                cpa = cpa->next;
                cpb = cpb->next;
            }
        }
    }

    if(cpa) {
        p->next = cpa;
    }
    if(cpb){
        p->next = cpb;
        while(cpb){
            cpb->Coef *= -1; // 改变系数的符号,将减数多项式的系数变为负的
            cpb = cpb->next;
        }
    }
    free(*pb);      //*pb已经为空,释放空间
}

void Multiply(polynomial **pa, polynomial **pb)
{
    polynomial *cpa, *ccpa;
    cpa = *pa;                      //保存着原pa的内容
    CreatePolyn(pa, 0);         //从新初始化pa为头结点
    (*pb) = (*pb)->next;
    while(*pb)                      //只要*pb不为NULL一直进行
    {
        Copy(&ccpa, cpa);      //将后者复制给前者
        MultiplyOperate(ccpa, *pb); 
        Add(pa, &ccpa);        //将结果加入到pa中,直到得到最后的结果
        (*pb) = (*pb)->next;
    }

}

void Copy(polynomial **pa, polynomial *pb)
{
    CreatePolyn(pa, 0);
    polynomial *temp, *cpa;
    cpa = *pa;
    pb = pb->next; // 移动指针指向第一个节点
    while(pb)
    {
        //进行复制操作
        temp = (polynomial *)malloc(sizeof(polynomial));
        temp->Coef = pb->Coef;
        temp->Index = pb->Index;
        temp->next = NULL;
        cpa->next = temp;
        cpa = temp;
        pb = pb->next;
    }
}

void MultiplyOperate(polynomial *pa, polynomial *pb)
{
    pa = pa->next;
    while(pa)
    {
        pa->Coef *= pb->Coef;
        pa->Index += pb->Index;
        pa = pa->next;
    }
}

void Print(polynomial *p)
{
    polynomial *temp = p->next;
    int a[100000];
    double b[100000];
    int aid=0,bid=0;
    int cnt=0;
    cout << "升幂情况: " ;
    while(temp){
        if(cnt!=0&& temp->Coef > 0)printf("+");
        b[bid]=  temp->Coef;
        a[aid]=  temp->Index;
        cout << b[bid] << "x^" << a[aid];
        aid++;
        bid++;
        cnt++;
        temp = temp->next;
    }
    if(cnt==0) {    //如果是空的输出0
        cout << "0";
    }
    cout << endl;
    cout << "降幂情况: ";
    int ans=0;
    for(int i=aid-1; i>=0; i--){
        if(ans!=0&&b[i]>0) {
            cout << "+";
        }
        cout << b[i] << "x^" << a[i];
        ans++;
    }
}

该题的链表方法讲解就结束了,后续我会补充结构体数组对此题的解法,希望大家多多指教!

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一元多项式计算器是一个基于数据结构的程序,用于对一元多项式进行加、减、乘等运算。一元多项式可以表示为:a0 + a1x + a2x^2 + ... + anx^n,其中a0, a1, a2, ..., an为系数,n为次数。常见的数据结构有顺序存储结构和链式存储结构。 在顺序存储结构中,可以使用数组来存储一元多项式,数组下标表示次数,数组元素表示系数。在链式存储结构中,可以使用链表来存储一元多项式,每个节点表示一项,包含系数和次数两个元素。 对于一元多项式的加、减、乘运算,可以分别使用不同的算法来实现。例如,对于加法运算,可以先将两个多项式按照次数从高到低排序,然后从高次项开始逐项相加,最后得到结果多项式。对于乘法运算,可以使用暴力法或者快速傅里叶变换(FFT)等算法来实现。 下面是一个简单的Python代码示例,用于实现一元多项式的加法运算: ```python class PolyNode: def __init__(self, coef, exp): self.coef = coef self.exp = exp self.next = None def add_poly(poly1, poly2): dummy = PolyNode(0, 0) tail = dummy while poly1 and poly2: if poly1.exp > poly2.exp: tail.next = PolyNode(poly1.coef, poly1.exp) poly1 = poly1.next elif poly1.exp < poly2.exp: tail.next = PolyNode(poly2.coef, poly2.exp) poly2 = poly2.next else: coef = poly1.coef + poly2.coef if coef != 0: tail.next = PolyNode(coef, poly1.exp) poly1 = poly1.next poly2 = poly2.next tail = tail.next tail.next = poly1 if poly1 else poly2 return dummy.next ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小侯不躺平.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值