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

该博客介绍了如何使用C++模板设计稀疏一元多项式的抽象数据类型,并实现两个有序单链表表示的稀疏多项式的加法计算。算法要求在原存储空间上进行,计算后不再保留第二个多项式链表,同时删除系数为0的项。文章提供了链表模板类和多项式加法函数的原型,以及解题代码示例。
摘要由CSDN通过智能技术生成

问题描述 :

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

内容:

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

 

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

 

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

注意:加/减法计算后,如某一项的结果系数为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 ElemType1 &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
-8 22 -9
1 7 8

输出范例 :

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

7.1-4.8x-0.3x^7+5x^17-8x^100

解题代码: 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <sstream>
#include <stack>
#include <map>
#include <ctime>
#include <array>
#include <set>
#include <list>
using namespace std;
//???ADT
/* ???????? */
template <class ElemType>
struct LinkNode
{
    ElemType data;            //??
    LinkNode<ElemType> *next; //next??
    LinkNode(LinkNode<ElemType> *ptr = NULL)
    {
        //???????????next??
        next = ptr;
    }
    LinkNode(const ElemType &item, LinkNode<ElemType> *ptr = NULL)
    {
        //?????????????????:??+next???
        next = ptr;
        data = item;
    }
};
//????????
template <class ElemType>
class LinkList
{
private:
    LinkNode<ElemType> *head;     // ???
    LinkNode<ElemType> *tail;     // ???
    void empty_push(ElemType num) //??????????
    {
        head = new LinkNode<ElemType>; //?????????
        tail = head;                   //????????
        head->data = num;              //??
        //head->next = NULL;
        return;
    }
    bool check_P(int n) //????????:0-n
    {
        if (0 <= n && n < size())
            return true;
        return false;
    }

public:
    /*
	
	int size(void)????
	LinkNode<ElemType>* get_address(int i)//?????????
	void have_look(void)   //??
	void push_back(ElemType num) //????
	void insert_head(ElemType num) ????
	bool insert_back(int place, ElemType num) ?????????

	*/
    LinkList()
    {
        //????????
        //head = new LinkNode<ElemType>;//?????????
        //tail = head;//????????
        head = NULL;
        tail = NULL;
    }
    LinkList(const ElemType &item)
    {
        //???????? ??????????
        head = new LinkNode<ElemType>(item);
        tail = head;
    }
    LinkList(LinkList<ElemType> &List)
    {
        //??????
        ;
    }
    ~LinkList()
    {
        //????
    }
    LinkNode<ElemType> *get_address(int i) //?????????
    {
        LinkNode<ElemType> *pla = head;
        while (i--)
        {
            pla = pla->next;
        }
        return pla;
    }
    void have_look(void)
    {
        LinkNode<ElemType> *p = head;
        while (p->next != NULL)
        {
            cout << p->data;
            cout << "->";
            p = p->next;
        }
        cout << p->data << endl;
        return;
    }
    int size(void) //finish ???????
    {
        int len = 0;
        if (head == NULL && tail == NULL)
            return 0;
        LinkNode<ElemType> *p;
        p = head;
        while (p != NULL)
        {
            len++;
            p = p->next;
        }
        return len;
    }
    void push_back(ElemType num)
    {
        if (size() == 0) //?????
        {
            empty_push(num);
            return;
        }
        LinkNode<ElemType> *p = new LinkNode<ElemType>; //????
        p->data = num;                                  //??
        tail->next = p;                                 //???????next???p
        tail = p;                                       //?????p
        return;
    }
    void insert_head(ElemType num)
    {
        if (size() == 0) //?????
        {
            empty_push(num);
            return;
        }
        LinkNode<ElemType> *p = new LinkNode<ElemType>; //????
        p->data = num;                                  //??
        p->next = head;                                 //??
        head = p;
        return;
    }
    bool insert_back(int place, ElemType num)
    {
        if (size() == 0 && place == 0) //?????
        {
            empty_push(num);
            return true;
        }
        if (check_P(place) == false) //???????
            return false;
        if (place == size() - 1) //??????
        {
            push_back(num);
            return true;
        }
        LinkNode<ElemType> *p = get_address(place);
        LinkNode<ElemType> *p2 = new LinkNode<ElemType>; //??
        p2->data = num;                                  //??
        p2->next = p->next;                              //??
        p->next = p2;                                    //??
        return true;
    }
    LinkNode<ElemType> *get_front(LinkNode<ElemType> *p) //??????????,???????????.
    {
        LinkNode<ElemType> *p1;
        p1 = head;
        while (p1->next != NULL)
        {
            if (p1->next == p)
                return p1;
            p1 = p1->next;
        }
    }
    bool del(int i) //????????  ???,?????????(0->n-1)
    {
        return del_p(get_address(i));
    }
    bool del_p(LinkNode<ElemType> *p)
    {
        if (size() == 0)
            return false;
        if (head == tail)
        {
            if (p == head)
            {
                delete head;
                head = NULL;
                tail = NULL;
                return true;
            }
            else
                return false;
        }
        if (p == head)
        {
            LinkNode<ElemType> *p1 = head->next;
            delete head;
            head = p1;
            return true;
        }
        if (p == tail)
        {
            LinkNode<ElemType> *p1 = get_front(p);
            delete p;
            p1->next = NULL;
            tail = p1;
            return true;
        }
        LinkNode<ElemType> *p1 = get_front(p);
        p1->next = p->next;
        delete p;
        return true;
    }
    ElemType at(int i)
    {
        LinkNode<ElemType> *p = get_address(i);
        return p->data;
    }
    void reverse(int m, int n) //??m->n??
    {
        m++, n++;
        LinkNode<ElemType> *newHead = new LinkNode<ElemType>;
        newHead->next = head;
        LinkNode<ElemType> *p = newHead;
        for (int i = 0; i < m - 1; i++)
            p = p->next;
        LinkNode<ElemType> *start = p->next;
        LinkNode<ElemType> *t = start->next;
        if (n == size())
        {
            tail = start;
        }
        for (int i = m; i < n; i++)
        {
            start->next = t->next;
            t->next = p->next;
            p->next = t;
            t = start->next;
        }
        head = newHead->next;
        return;
    }
    LinkList<ElemType> *get_head(void)
    {
        return head;
    }
    LinkList<ElemType> *get_tail(void)
    {
        return head;
    }
    void pick(LinkList<ElemType> &lis)
    {
        tail->next = lis.head;
        tail = lis.tail;
        return;
    }
};
//LinkList<int> a;
vector<double> departString_double(string data)
{
    vector<double> back_part; //output type
    int i, j;
    vector<string> part;
    string A_part;
    stringstream room;
    room.str(data);
    while (room >> A_part)
        part.push_back(A_part);
    for (i = 0; i < part.size(); i++)
    {
        double num_cahe;
        num_cahe = atof(part[i].c_str());
        back_part.push_back(num_cahe);
    }
    return back_part;
}
template <class ElemType>
void output(list<ElemType> &A, list<ElemType> &B)
{
    bool ok = 0;
    auto j = B.begin();
    for (auto i = A.begin(); i != A.end(); i++)
    {

        if (*i == 0)
            ;
        else if (*j == 0)
            if (*i < 0)
                cout << *i, ok = 1;
            else if (ok)
                cout << '+' << *i, ok = 1;
            else
                cout << *i, ok = 1;
        else if (*j == 1)
            if (*i < 0)
                if (*i != -1)
                    cout << *i << "x", ok = 1;
                else
                    cout << "-x", ok = 1;
            else if (ok)
                if (*i != 1)
                    cout << '+' << *i << "x", ok = 1;
                else
                    cout << '+' << "x", ok = 1;
            else if (*i != 1)
                cout << *i << "x", ok = 1;
            else
                cout << "x", ok = 1;
        else if (*i < 0)
            if (*i != -1)
                cout << *i << "x^" << *j, ok = 1;
            else
                cout << '-' << "x^" << *j, ok = 1;
        else if (ok)
            if (*i != 1)
                cout << '+' << *i << "x^" << *j, ok = 1;
            else
                cout << '+' << "x^" << *j, ok = 1;
        else if (*i != 1)
            cout << *i << "x^" << *j, ok = 1;
        else
            cout << "x^" << *j, ok = 1;
        j++;
    }
    if (ok == 0)
        cout << 0 << endl;
    cout << endl;
    return;
}
int main()
{
    int i, j;
    vector<double> a_f, a_i;
    vector<double> b_f, b_i;
    string l1, l2, l3, l4;
    bool oper;
    cin >> oper;
    cin.get();
    getline(cin, l1);
    getline(cin, l2);
    getline(cin, l3);
    getline(cin, l4);
    a_f = departString_double(l1);
    a_i = departString_double(l2);
    b_f = departString_double(l3);
    b_i = departString_double(l4);
    //output(a_f);
    //output(a_i);
    //output(b_f);
    //output(b_i);
    list<double> A_f, B_f, A_i, B_i;
    for (i = 0; i < a_f.size(); i++)
        A_f.push_back(a_f[i]);
    for (i = 0; i < a_i.size(); i++)
        A_i.push_back(a_i[i]);
    for (i = 0; i < b_f.size(); i++)
        B_f.push_back(b_f[i]);
    for (i = 0; i < b_i.size(); i++)
        B_i.push_back(b_i[i]);
    output(A_f, A_i);
    output(B_f, B_i);
    cout << endl;
    auto I_1 = A_f.begin(), I_2 = A_i.begin();
    auto I_3 = B_f.begin(), I_4 = B_i.begin();
    list<double> ans_f, ans_i;
    while (I_2 != A_i.end())
    {
        while (I_4 != B_i.end() && *I_4 < *I_2)
        {
            if (!oper)
                ans_f.push_back(*I_3);
            else
                ans_f.push_back(-*I_3);
            ans_i.push_back(*I_4);
            I_3++;
            I_4++;
        }
        if (*I_2 == *I_4)
        {
            if (oper)
            {
                ans_f.push_back(*I_1 - *I_3);
                ans_i.push_back(*I_4);
            }
            else
            {
                ans_f.push_back(*I_3 + *I_1);
                ans_i.push_back(*I_4);
            }
            I_3++;
            I_4++;
        }
        else
        {
            ans_f.push_back(*I_1);
            ans_i.push_back(*I_2);
        }
        I_1++;
        I_2++;
    }
    while (I_4 != B_i.end())
    {
        if (!oper)
            ans_f.push_back(*I_3);
        else
            ans_f.push_back(-*I_3);
        ans_i.push_back(*I_4);
        I_3++;
        I_4++;
    }
    output(ans_f, ans_i);
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值