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

28 篇文章 5 订阅

问题描述 :

目的:使用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 &A, poly_LinkList &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;

};

题解

#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
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; }
    //设置链表头指针
    void SetHead(LinkNode<ElemType1, ElemType2>* p) { head = p; }
    //设置链表尾指针
    void SetTail(LinkNode<ElemType1, ElemType2>* p) { tail = p; }
    bool push_back(ElemType1 x1, ElemType2 x2)
    {
        LinkNode <ElemType1, ElemType2>* p = new LinkNode<ElemType1, ElemType2>(x1, x2);
        tail->next = p;
        SetTail(p);
        return 1;
    }
    poly_LinkList(ElemType1 item1[], ElemType2 item2[], int num)
    {
        int i = 0;
        head = new LinkNode<ElemType1, ElemType2>(item1[0],item2[0]); tail = head;
        for (i = 1; i < num; i++) {
            push_back(item1[i], item2[i]);
        }
    }
    //在首节点之前插入一个结点
    bool InsFirst(ElemType1 fact, ElemType2 indi)
    {
        LinkNode <ElemType1, ElemType2>* p = new LinkNode<ElemType1, ElemType2>(fact, indi);
        p->next = GetHead();
        SetHead(p);
        return 1;
    }
    //获取链表头结点
    LinkNode<ElemType1, ElemType2>* GetHead() { return head; }
    //获取链表尾结点
    LinkNode<ElemType1, ElemType2>* GetTail() { return tail; }
    //删除链表的第pos个位置的元素
    ElemType2 ListDelete(int pos)
    {
        LinkNode <ElemType1, ElemType2>* p = GetHead();
        if (pos == 0) {
            p = head;
            head = head->next;
            if (tail == p)
                tail = head;
            delete p;
            return 1;
        }
        else if (pos == 1) {
            if (tail == p->next)
                tail = head;
            p = p->next;
            head->next = head->next->next;
            delete p;
            return 1;
        }
        LinkNode <ElemType1, ElemType2>* q = p;
        int pos1 = pos-1;
        while (--pos)
            p = p->next;
        while (--pos1)
            q = q->next;
        if (tail == p)
            tail == q;
        q->next = p->next;
        delete p;
        return 1;
    }
    bool ListTraverse()
    {
        LinkNode <ElemType1, ElemType2>* p = GetHead();
        while (p != NULL) {
            if (p == GetHead()) {
                if ((p->factor != 1 && p->factor != -1)||p->indice==0)
                    cout << p->factor;
                else if (p->factor == -1)
                    cout << "-";
                if (p->indice != 0 && p->indice != 1)
                    cout << "x^" << p->indice;
                else if (p->indice == 1)
                    cout << "x";
            }
            else {
                if (p->factor > 0 && p->factor != 1) {
                    cout << "+" << p->factor;
                }
                else if (p->factor < 0 && p->factor != -1)
                    cout  << p->factor;
                else if (p->factor == 1)
                    cout << "+";
                else if (p->factor == -1)
                    cout << "-";
                if (p->indice != 0 && p->indice != 1)
                    cout << "x^" << p->indice;
                else if (p->indice == 1)
                    cout << "x";
            }
            p = p->next;
        }
        return 1;
    }
    void Add_Poly(poly_LinkList<ElemType1,ElemType2>& A, poly_LinkList<ElemType1,ElemType2>& B, int add_sub)
    {
        LinkNode <ElemType1, ElemType2>* p = A.GetHead();
        LinkNode <ElemType1, ElemType2>* q = B.GetHead();
            while (p != NULL) {
                 if (q != NULL) {
                    if (p->indice == q->indice) {
                        if (add_sub == 1)
                            p->factor += q->factor;
                        else
                            p->factor -= q->factor;
                        q = q->next;
                        B.ListDelete(0);
                        if (p->next == NULL)
                            continue;
                    }
                    else if (p->indice > q->indice) {
                        if (add_sub == 1)
                        A.InsFirst(q->getFactor(), q->getIndice());
                        else
                            A.InsFirst(-q->getFactor(), q->getIndice());
                        q = q->next;
                        B.ListDelete(0);
                        continue;
                    }
                    else if ((p->indice < q->indice) && (p->next != NULL) && (p->next->indice > q->indice)) {
                        if (add_sub == 1) {
                            ElemType1 v1 = q->factor; ElemType2 v2 = q->indice;
                            LinkNode <ElemType1, ElemType2>* v = new LinkNode<ElemType1, ElemType2>(v1, v2);
                            v->next = p->next; p->next = v;
                            q = q->next;
                            B.ListDelete(0);
                            continue;
                        }
                        else {
                            ElemType1 v1 = -q->factor; ElemType2 v2 = q->indice;
                            LinkNode <ElemType1, ElemType2>* v = new LinkNode<ElemType1, ElemType2>(v1, v2);
                            v->next = p->next; p->next = v;
                            q = q->next;
                            B.ListDelete(0);
                            continue;
                        }  
                    }
                    else if ((p->indice < q->indice) && (p->next == NULL)) {
                        if (add_sub == 1)
                        A.push_back(q->factor, q->indice);
                        else
                            A.push_back(-q->factor, q->indice);
                        q = q->next;
                        B.ListDelete(0);
                        if (q != NULL)
                            continue;
                    }
                }
                p = p->next;
            }
        int num = 0;
        p = A.GetHead();
        while (p != NULL) {
            if (p->factor == 0) {
                p = p->next;
                A.ListDelete(num);
                continue;
            }
            p = p->next;
            num++;
        }
    }
};
int main()
{
    double factor1[10000] = { 0 }, factor2[10000] = { 0 };
    int indice1[10000] = { 0 }, indice2[10000] = { 0 }, num1 = 0, ok = 0;
    string str;
    cin >> ok;
    if (ok == 0) ok = 1;
    else ok = 0;
    cin.get();
    getline(cin, str);
    char ch = 0;
    int i = 0; int a = 0, b = 0; double s = 0;
    for (i = 0; i < str.size(); i++) {
        if (str[i] != ' ') {
            s = 0;
            bool jk = 0, kk = 0;; int m = 0;
            if (str[i] == '-') {
                jk = 1;
                i++;
            }
            while (str[i] != ' ' && str[i] != 0) {
                ch = str[i];
                if (ch == '.') {
                    kk = 1;
                    i++; continue;
                }
                s *= 10;
                s += ch - '0';
                if (kk == 1)
                    m++;
                i++;
            }
            int sum = 1;
            while (m--)
                sum *= 10;
            s /= sum;
            if (jk == 1) s = -s;
            factor1[num1] = s; num1++;
        }
    }
    int num2 = 0;
    getline(cin, str);
    for (i = 0; i < str.size(); i++) {
        if (str[i] != ' ') {
            a = 0;
            bool jk = 0;
            if (str[i] == '-') {
                jk = 1;
                i++;
            }
            while (str[i] != ' ' && str[i] != 0) {
                ch = str[i];
                a *= 10;
                a += ch - '0';
                i++;
            }
            if (jk == 1) a = -a;
            indice1[num2] = a; num2++;
        }
    }
    int num3 = 0;
    getline(cin, str);
    for (i = 0; i < str.size(); i++) {
        if (str[i] != ' ') {
            s = 0;
            bool jk = 0, kk = 0;; int m = 0;
            if (str[i] == '-') {
                jk = 1;
                i++;
            }
            while (str[i] != ' ' && str[i] != 0) {
                ch = str[i];
                if (ch == '.') {
                    kk = 1;
                    i++; continue;
                }
                s *= 10;
                s += ch - '0';
                if (kk == 1)
                    m++;
                i++;
            }
            int sum=1;
            while (m--)
                sum *= 10;
            s /= sum;
            if (jk == 1) s = -s;
            factor2[num3] = s; num3++;
        }
    }
    int num4 = 0;
    getline(cin, str);
    for (i = 0; i < str.size(); i++) {
        if (str[i] != ' ') {
            a = 0;
            bool jk = 0;
            if (str[i] == '-') {
                jk = 1;
                i++;
            }
            while (str[i] != ' ' && str[i] != 0) {
                ch = str[i];
                a *= 10;
                a += ch - '0';
                i++;
            }
            if (jk == 1) a = -a;
            indice2[num4] = a; num4++;
        }
    }
    poly_LinkList <double, int> A(factor1, indice1, num1);
    poly_LinkList <double, int> B(factor2, indice2, num3);
    A.ListTraverse();
    cout << endl;
    B.ListTraverse();
    cout << endl << endl;
    A.Add_Poly(A,B,ok);
    if (A.GetHead() != NULL)
        A.ListTraverse();
    else
        cout << "0";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值