一元多项式的表示和相加

一元多项式的表示和相加是数据结构(C语言)中的一个简单的问题,这里我们用C++的一些东西来实现它。(简洁版)

首先是表示多项式,多项式有一些列的单项组成,每一项都有系数和指数两个量,考虑到多项式的长度和指数的不确定性,显而易见,应该使用链表来存储它。

由上面的叙述很容易得到单项的结构:

struct Poly
{
    int first;
    int second;
    Poly *next;
};

first代表单项的常数,second表示指数,next代表下个节点的所在,这个结构体十分的简单。

接下来是多项式的表示,我把它设计为一个类:

class Polynomial
{
public:
    Polynomial();
    void insert(int ,int); //插入,核心步骤
    Polynomial(const Polynomial&);//拷贝构造函数

    friend Polynomial operator +(const Polynomial&,const Polynomial&);//重载+运算符

    ~Polynomial(); //析构函数

    void print();//打印多项式

private:
    Poly *get_new_poly(int ,int);//得到一个新的单项

    Poly *head;链表的头结点
};

当然,这个类的设计有一些问题,这里不做详细的描述,比如我少写了重载赋值运算符。

首先是打印函数的实现:

void Polynomial::print()
{
    Poly *p=head->next;
    while(p!=NULL)
    {
        cout<<p->first<<"   "<<p->second<<endl;
        p=p->next;
    }
}

不做太多的描述。

下面是两个构造函数:

Polynomial::Polynomial():head(NULL)
{
    head=get_new_poly(0,0);
}

Polynomial::Polynomial(const Polynomial&poly):head(NULL)
{
    head=get_new_poly(0,0);

    Poly *p=poly.head->next;
    while(p!=NULL)
    {
        this->insert(p->first,p->second);
        p=p->next;
    }
}

这里我把头结点赋予了一个常数为0,指数为0的单项,这是为了后面算法实现的 方便,无实际意义,也可以看到insert()函数的重要性。

接下来是析构函数和辅助函数,也很简单。

Polynomial::~Polynomial()
{
    Poly *p=head;
    while(p!=NULL)
    {
        Poly *pp=p;
        p=p->next;
        delete pp;
    }
}

Poly *Polynomial::get_new_poly(int first,int second)
{
    Poly *poly=new Poly;
    assert(poly!=NULL);
    poly->first=first;
    poly->second=second;
    poly->next=NULL;
    return poly;
}

接下来开始最重要的insert()函数,这个函数完成插入工作,在其中完成自动的排序以及一些其它的工作。

两个多项式相加得到一个新的多项式,就可以看做先把一个多项式插入进新的空的多项式中,然后再把另一个多项式也插入其中,其时间复杂度依旧是O(f(N1)+G(N2)),不变。

void Polynomial::insert(int first,int second)
{

    Poly *p_s=head->next,*p_e=head;
    while(p_s!=NULL)
    {
        if(p_s->second == second)
        {
            p_s->first+=first;
            if(p_s->first==0)
            {
                p_e->next=p_s->next;
                delete p_s;
            }
            return;
        }
        else if(p_s->second < second )
        {
            p_e=p_s;
            p_s=p_s->next;
        }
        else
            break;
    }
    Poly *poly=get_new_poly(first,second);

    p_e->next=poly;
    poly->next=p_s;
}

这个函数中,p_s参与实际的比较和循环,p_e指向的是p_s的前一个节点。

当插入的加点与p_s的指数相同的时候,这个时候不需要新的节点来链接它,只需要常数相加即可,如果结果常数项为0,就删除p_s节点,同时也意味着此次插入完成。
如果p_s的指数项比要插入的项的指数项小,那么更新p_s为链表的下个节点,直到满足条件。
如果p_s的指数项大于要插入的项的指数,那么完成插入操作。

接下来就是重载+操作符的操作:

Polynomial operator +(const Polynomial&poly1,const Polynomial&poly2)
{
    Polynomial poly;
    Poly *p_head=poly1.head->next;
    while(p_head!=NULL)
    {
        poly.insert(p_head->first,p_head->second);
        p_head=p_head->next;
    }
    p_head=poly2.head->next;
    while(p_head!=NULL)
    {
        poly.insert(p_head->first,p_head->second);
        p_head=p_head->next;
    }
    return poly;
}

分别将两个多项式的每一项插入到新的多项式中。

下面为我写的一个测试代码:

int main()
{
    Polynomial poly1,poly2;

    poly1.insert(1,1);
    poly1.insert(-1,2);
    poly2.insert(1,2);
    poly2.insert(2,8);

    Polynomial poly3=poly1+poly2;

    poly3.print();
}

下图为我的测试结果:

测试结果

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值