DHU数据结构-单链表-ADT应用-单链表实现一元多项式的加/减法运算

目录

1.题目

2.题解

3.代码实现


1.题目

有序链表ADT模板简单应用算法设计:一元多项式的加/减法运算

作者: 冯向阳 时间限制: 1S 章节: DS:线性表

问题描述 :

目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,稍加改动,针对一元多项式建立相应的稀疏多项式ADT,使用单链表ADT的基本操作,设计并实现稀疏一元多项式的加法计算的算法设计。

内容:(1)请参照单链表的ADT模板,设计稀疏一元多项式的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的单链表ADT原型文件,自行设计稀疏一元多项式的ADT。)

(2)ADT的简单应用:使用该ADT设计并实现稀疏一元多项式的加法计算的算法设计。

应用1:假设2个稀疏一元多项式分别由带头结点的有序单链表A和B存储。现要求设计一个算法,实现稀疏一元多项式的加减法计算。要求使用A和B的原存储空间,且计算后B不再单独存在。输入中的单链表的长度不得在计算算法中利用,仅作为建表使用。

假定:系数项的数据类型为double,指数项的数据类型为int,指数项递增有序,多项式至少有1项,系数项均不为0。

注意:加/减法计算后,如某一项的结果系数为0,则该项要从多项式链表中删除。

参考函数原型:

template<class ElemType1,class ElemType2>

void Add_Poly( poly_LinkList<ElemType> &A, poly_LinkList<ElemType> &B, int add_sub );

有序链表模板类原型(用于一元多项式计算)参考如下:

/* 单链表的结点定义 */(用于一元多项式计算)

template<class ElemType1, class ElemType2>
struct LinkNode
{
    ElemType1 factor; //系数 
    ElemType2 indice;  //指数 
    LinkNode<ElemType1, ElemType2> *next;
    LinkNode(LinkNode<ElemType1, ElemType2> *ptr = NULL){next = ptr;} //构造函数1,用于构造头结点
    LinkNode(const ElemType1 &item1, const ElemType2 &item2, LinkNode<ElemType1, ElemType2> *ptr = NULL) //构造函数2,用于构造其他结点   
    //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
    {
        next = ptr;
        factor = item1;
        indice = item2;
    }
    ElemType1 getFactor(){ return factor;}  //取得结点中的系数 
    ElemType2 getIndice(){ return indice;}  //取得结点中的指数 
    void SetLink( LinkNode<ElemType1, ElemType2> *link ){ next = link; }  //修改结点的next域 
    void SetFactor( ElemType1 value ){ factor = value; }   //修改结点的系数 
    void SetIndice( ElemType2 value ){ indice = value; }   //修改结点的指数 
};

//带头结点的单链表(用于一元多项式计算) 
template<class ElemType1, class ElemType2>
class poly_LinkList{
   private:
      LinkNode<ElemType1, ElemType2> *head;   // 头结点
      LinkNode<ElemType1, ElemType2> *tail;   // 尾结点
   public:
      //无参数的构造函数
      poly_LinkList(){head = new LinkNode<ElemType1, ElemType2>; tail = head;}
      //带参数的构造函数
      poly_LinkList(const ElemType1 &item1, const ElemType2 &item2 ){head = new LinkNode<ElemType1, ElemType2>(item1, item2); tail = head;}
      //拷贝构造函数
      poly_LinkList(poly_LinkList<ElemType1, ElemType2> &List);
      //析构函数
      ~poly_LinkList(){ListDestroy();}
      //销毁链表
      void ListDestroy();
      //清空链表
      void ListClear(); 
      //返回链表的长度
      int ListLength() const;
      //判断链表是否为空表
      bool ListEmpty() const;
      //在首节点之前插入一个结点
      bool InsFirst( ElemType1 fact, ElemType2 indi );
      //获取链表头结点
      LinkNode<ElemType1,ElemType2>* GetHead() { return head;}
      //设置链表头指针
      void SetHead(LinkNode<ElemType1,ElemType2> *p){ head = p;}      
      //设置链表尾指针
      void SetTail(LinkNode<ElemType1,ElemType2> *p){ tail = p;}      

      //获取链表尾结点
      LinkNode<ElemType1,ElemType2>* GetTail() { return tail;}
      //返回链表的第i个元素的系数值 
      ElemType1 GetElem_factor(int pos);
      //返回链表的第i个元素的指数值 
      ElemType2 GetElem_indice(int pos);
      //在链表的第pos个位置之前插入e元素
      bool ListInsert_prior(int pos, ElemType1 fact, ElemType2 indi);
      //在链表的第pos个位置之后插入e元素
      bool ListInsert_next(int pos, ElemType1 fact, ElemType2 indi);
      //表头插入法动态生成链表
      void CreateList_Head(vector<ElemType1> &Factor, vector<ElemType2> &Indice);      
      //表尾插入法动态生成链表
      void CreateList_Tail(vector<ElemType1> &Factor, vector<ElemType2> &Indice);     
      //删除链表的第pos个位置的元素
      ElemType2 ListDelete(int pos);
      //按序号查找,从链表的第一个结点开始,判断当前结点是否是第i个,
      //若是,则返回该结点的数据域的值;否则继续后一个,直至表结束。没有第i个结点时返回空。 
      bool FindElem( int k, ElemType1 &fact, ElemType2 &indi);
      //bool compare(ElemType a, ElemType *b);
      //按值查找,即定位。从链表的第一个结点开始,判断当前结点值是否等于e。
      //若是,则返回该结点的序号;否则继续后一个,直至表结束。找不到时返回0。 
      int SearchElem( const ElemType2 &e) const;
      //返回链表给定数据元素的后继数据元素的值
      bool NextElem(LinkNode<ElemType1, ElemType2> *p, ElemType1 &fact, ElemType2 &indi); 
      //遍历链表
      bool ListTraverse() const;
};

输入说明 :

第一行:加/减法选择(0:加法  1:减法)

第二行:一元多项式A的各项的系数(系数之间以空格分隔)

第三行:一元多项式A的各项的指数(指数之间以空格分隔)

第四行:一元多项式B的各项的系数(系数之间以空格分隔)

第五行:一元多项式B的各项的指数(指数之间以空格分隔)

输出说明 :

见测试数据样例

输入范例 :

0
7.1 3.2 -22.3 9 5 -8
0 1 7 8 17 100
-3.2 22 -9
1 7 18

输出范例 :

7.1+3.2x-22.3x^7+9x^8+5x^17-8x^100
-3.2x+22x^7-9x^18

7.1-0.3x^7+9x^8+5x^17-9x^18-8x^100


2.题解

  • 挖坑,注意数据输出的处理(属实是麻烦

3.代码实现

  • 完整代码
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <sstream>
    using namespace std;
    
    //单链表的结点定义 (用于一元多项式计算)
    template<class ElemType1, class ElemType2>
    struct LinkNode
    {
        ElemType1 factor; //系数
        ElemType2 indice;  //指数
        LinkNode<ElemType1, ElemType2> *next;
        LinkNode(LinkNode<ElemType1, ElemType2> *ptr = NULL)
        {
            next = ptr;   //构造函数1,用于构造头结点
        }
        LinkNode(const ElemType1 &item1, const ElemType2 &item2, LinkNode<ElemType1, ElemType2> *ptr = NULL) //构造函数2,用于构造其他结点
        //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
        {
            next = ptr;
            factor = item1;
            indice = item2;
        }
        ElemType1 getFactor()
        {
            return factor;   //取得结点中的系数
        }
        ElemType2 getIndice()
        {
            return indice;   //取得结点中的指数
        }
        void SetLink( LinkNode<ElemType1, ElemType2> *link )
        {
            next = link;    //修改结点的next域
        }
        void SetFactor( ElemType1 value )
        {
            factor = value;    //修改结点的系数
        }
        void SetIndice( ElemType2 value )
        {
            indice = value;    //修改结点的指数
        }
    };
    //带头结点的单链表(用于一元多项式计算)
    template<class ElemType1, class ElemType2>
    class poly_LinkList
    {
    private:
        LinkNode<ElemType1, ElemType2> *head;   // 头结点
        LinkNode<ElemType1, ElemType2> *tail;   // 尾结点
    public:
        //无参数的构造函数
        poly_LinkList()
        {
            head = new LinkNode<ElemType1, ElemType2>;
            tail = head;
        }
        //带参数的构造函数
        poly_LinkList(const ElemType1 &item1, const ElemType2 &item2 )
        {
            head = new LinkNode<ElemType1, ElemType2>(item1, item2);
            tail = head;
        }
        //拷贝构造函数
        poly_LinkList(poly_LinkList<ElemType1, ElemType2> &List);
        //析构函数
        ~poly_LinkList()
        {
            ListDestroy();
        }
        //销毁链表
        void ListDestroy();
        //清空链表
        void ListClear();
        //返回链表的长度
        int ListLength() const;
        //判断链表是否为空表
        bool ListEmpty() const;
        //在首节点之前插入一个结点
        bool InsFirst( ElemType1 fact, ElemType2 indi );
        //获取链表头结点
        LinkNode<ElemType1,ElemType2>* GetHead()
        {
            return head;
        }
        //设置链表头指针
        void SetHead(LinkNode<ElemType1,ElemType2> *p)
        {
            head = p;
        }
        //设置链表尾指针
        void SetTail(LinkNode<ElemType1,ElemType2> *p)
        {
            tail = p;
        }
        //获取链表尾结点
        LinkNode<ElemType1,ElemType2>* GetTail()
        {
            return tail;
        }
        //返回链表的第i个元素的系数值
        ElemType1 GetElem_factor(int pos);
        //返回链表的第i个元素的指数值
        ElemType2 GetElem_indice(int pos);
        //在链表的第pos个位置之前插入e元素
        bool ListInsert_prior(int pos, ElemType1 fact, ElemType2 indi);
        //在链表的第pos个位置之后插入e元素
        bool ListInsert_next(int pos, ElemType1 fact, ElemType2 indi);
        //表头插入法动态生成链表
        void CreateList_Head(vector<ElemType1> &Factor, vector<ElemType2> &Indice);
        //表尾插入法动态生成链表
        void CreateList_Tail(vector<ElemType1> &Factor, vector<ElemType2> &Indice);
        //删除链表的第pos个位置的元素
        ElemType2 ListDelete(int pos);
        //按序号查找,从链表的第一个结点开始,判断当前结点是否是第i个,
        //若是,则返回该结点的数据域的值;否则继续后一个,直至表结束。没有第i个结点时返回空。
        bool FindElem( int k, ElemType1 &fact, ElemType2 &indi);
        //bool compare(ElemType a, ElemType *b);
        //按值查找,即定位。从链表的第一个结点开始,判断当前结点值是否等于e。
        //若是,则返回该结点的序号;否则继续后一个,直至表结束。找不到时返回0。
        int SearchElem( const ElemType2 &e) const;
        //返回链表给定数据元素的后继数据元素的值
        bool NextElem(LinkNode<ElemType1, ElemType2> *p, ElemType1 &fact, ElemType2 &indi);
        //遍历链表
        void ListTraverse();
    };
    template<class T1,class T2>
    void poly_LinkList<T1,T2>::ListDestroy()
    {
        auto t=head;
        while(t)
        {
            delete head;
            t=t->next;
        }
    }
    template<class T1,class T2>
    void poly_LinkList<T1,T2>::ListTraverse()
    {
        int flag=0;
        auto it=head->next;
        auto t=head;
        for(it; it!=tail; it=t)
        {
            if(it->factor)
            {
                flag=1;
                if(abs(it->factor)!=1)cout<<(it->factor);
                if(it->factor==-1)cout<<'-';
    
                if(it->indice)
                {
                    if((it->indice)!=1)
                        cout<<"x^"<<(it->indice);
                    else
                        cout<<'x';
                }
            }
            t=it->next;
            if((t->factor)>0)
                cout<<'+';
        }
    
        if(it->factor)
            {
                flag=1;
                if(abs(it->factor)!=1)cout<<(it->factor);
                if(it->factor==-1)cout<<'-';
    
                if(it->indice)
                {
                    if((it->indice)!=1)
                        cout<<"x^"<<(it->indice);
                    else
                        cout<<'x';
                }
            }
    
        if(!flag)cout<<0;
        cout<<endl;
    }
    
    template<class T>
    void f(stringstream &in,vector<T> &A)
    {
        T str;
        while(in>>str)
            A.push_back(str);
    }
    template<class T1,class T2>
    void poly_LinkList<T1,T2>::CreateList_Tail(vector<T1> &Factor, vector<T2> &Indice)
    {
        for(int i=0; i<Factor.size(); i++)
        {
            auto t=new LinkNode<T1,T2>(Factor[i],Indice[i]);
            tail->next=t;
            tail=t;
        }
    }
    
    template<class ElemType1,class ElemType2>
    void Add_Poly( poly_LinkList<ElemType1,ElemType2> &A, poly_LinkList<ElemType1,ElemType2> &B, int add_sub )
    {
        A.ListTraverse();
        B.ListTraverse();
        cout<<endl;
    
        auto ta=A.GetHead()->next;
        auto tb=B.GetHead()->next;
        auto t=A.GetHead();
        while(add_sub&&tb)
        {
            tb->factor=(-1)*tb->factor;
            tb=tb->next;
        }
        tb=B.GetHead()->next;
        while(ta && tb)
        {
            if(ta->indice < tb->indice)
            {
                t->next=ta;
                t=t->next;
                ta=ta->next;
            }
            else if(ta->indice > tb->indice)
            {
                t->next=tb;
                t=t->next;
                tb=tb->next;
            }
            else
            {
                double x=(ta->factor)+(tb->factor);
                ta->factor=x;
                t->next=ta;
                t=t->next;
                ta=ta->next;
                tb=tb->next;
            }
        }
        if(ta)
            t->next=ta;
        if(tb)
            t->next=tb;
    
        A.ListTraverse();
    }
    int main()
    {
        int n;
        string f1,i1,f2,i2;
        vector<double> F1,F2;
        vector<int> I1,I2;
        cin>>n;
        getchar();
        getline(cin,f1);
        getline(cin,i1);
        getline(cin,f2);
        getline(cin,i2);
        stringstream fa1(f1);
        stringstream in1(i1);
        stringstream fa2(f2);
        stringstream in2(i2);
    
        f(fa1,F1);
        f(in1,I1);
        f(fa2,F2);
        f(in2,I2);
    
        poly_LinkList<double,int> a,b;
        a.CreateList_Tail(F1,I1);
        b.CreateList_Tail(F2,I2);
    
        Add_Poly(a,b,n);
    
        return 0;
    }
    

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值