数据结构实习二2

实验要求:

1.设计带表头的结点的单链表表示多项式类。

2.在该类上增加成员函数void PolyMul(Polynominal &r),并重载*运算符。

3.实现菜单驱动的main函数,测试多项式的各个运算:输入多项式,显示多项式,以及多项式加法和乘法运算。

4.采用带表头的非循环链表存储多项式。

(其中polyadd函数也可以这样实现:

Polynominal::PolyAdd(Polynominal P1,Polynominal P2){
    Polynominal front,rear,temp;
    int sum;
    rear = (Polynominal)malloc(sizeof(struct PolyNode));
    front = rear;
    whie(P1 && P2){
        switch(Compare(P1->exp,P2->exp)){
            case 1:
                Attach(P1->coef,P1->exp,&rear);
                P1 = P1->link;
                break;
            case -1:
                Attach(P2->coef,P2->exp,&rear);
                P2 =P2->link;
                break;
            case 0:
                sum = P1->coef + P2->coef;
                if(sum) Attach(sum,P1->exp,&rear);
                P1 = P1->link;
                P2 = P2->link;
                break;
        }
    }
    for(;P1;P1=P1->link) Attach(sum,P1->coef,P1->exp,&rear);
    for(;P2;P2=P2->link) Attach(sum,P2->coef,P2->exp,&rear);
    rear->link = NULL;
    temp = front;
    front = front->link;
    free(temp);
    return front;
}

完整代码如下,但是关于PolyMul函数的实现,我们这些低能人容易出现一些问题,后将纠结的代码与合理的作比较微笑

#include <iostream> 
using namespace std;  
class Term  
{  
public:  
    Term(int c, int e);  
    Term(int c, int e, Term *nxt);  
    Term* InsertAfter(int c, int e); 
private:  
    int coef, exp;
    Term* link;
    friend ostream & operator << (ostream &, const Term &);  
    friend class Polynominal;  
};

Term::Term(int c, int e) : coef(c), exp(e)  
{  
    link = 0;  
} 

Term::Term(int c, int e, Term *nxt) : coef(c), exp(e)  
{  
    link = nxt;  
}

Term *Term::InsertAfter(int c, int e) 
{  
    link = new Term(c, e, link);  
    return link;  
}

ostream & operator << (ostream& out, const Term& val)  
{  
    if(val.coef == 0) return out;  
    out << val.coef;  
    switch(val.exp) {  
        case 0: break;  
        case 1: out << "x"; break;  
        default: out << "x^" << val.exp; break;  
    }  
    return out;  
}

class Polynominal  
{  
public:  
    Polynominal();  
    ~Polynominal();  
    void AddTerms(istream& in);  
    void Output(ostream& out) const;  
    void PolyAdd(Polynominal& r);  
    void PolyMul(Polynominal& r);  
private:  
    Term* theList;  
    friend ostream & operator << (ostream &, const Polynominal &);  
    friend istream & operator >> (istream &, Polynominal &);  
    friend Polynominal & operator + (Polynominal &, Polynominal &);  
    friend Polynominal & operator * (Polynominal &, Polynominal &);  
};

Polynominal::Polynominal()  
{  
    theList = new Term(0, -1);
    theList -> link = NULL;  
}

Polynominal::~Polynominal()
{
    Term *p = theList -> link;
    while(p != NULL) {
        theList -> link = p -> link;
        delete p;
        p = theList -> link;
    }
    delete theList;
}
void Polynominal::AddTerms(istream& in) 
{  
    Term* q = theList;  
    int c, e;  
    while(true) {  
        cout << "Input a term(coef, exp):\n";  
        cin >> c >> e;  
        q = q -> InsertAfter(c, e);
        if(e < 0) break;
    }  
}

void Polynominal::Output(ostream& out) const  
{  
    int first = 1;  
    Term *p = theList -> link;  
    for( ; p != NULL && p -> exp >= 0; p = p -> link) {  
        if(!first && (p -> coef > 0)) out << "+";  
        first = 0;  
        out << *p; 
    }  
    cout << "\n" << endl;  
}

void Polynominal::PolyAdd(Polynominal& r)
{
    Term *q, *q1 = theList, *p; // q1指向表头结点
    p = r.theList -> link; // p指向第一个要处理的结点
    q = q1 -> link; // q1是q的前驱,p和q就指向两个当前进行比较的项
    while(p != NULL && p -> exp >= 0) { // 对r的单链表遍历,直到全部结点都处理完
        while(p -> exp < q -> exp) { // 跳过q -> exp大的项
            q1 = q;
            q = q -> link;
        }
        if(p -> exp == q -> exp) { // 指数相等时,系数相加
            q -> coef = q -> coef + p -> coef;
            if(q -> coef == 0) { // 若相加后系数为0,则删除q
                q1 -> link = q -> link;
                delete (q);
                q = q1 -> link; // 重置q指针
            }
            else { // 若相加后系数不为0,则移动q1和q
                q1 = q;
                q = q -> link;
            }
        }
        else q1 = q1 -> InsertAfter(p -> coef, p -> exp); // 若p -> exp > q -> exp则以p的系数和指数生成新结点,插入q1后
        p = p -> link;
    }
}
void Polynominal::PolyMul(Polynominal& r)
{
    Polynominal result; // 存储结果
    Term *n = result.theList; // n指向result的头结点
    n = n -> InsertAfter(0, 0); // 将0, 0插入result的头结点之后
    Term *p = r.theList -> link; // p指向第一个要处理的结点
    while(p -> exp >= 0) { // 对r的单链表遍历,直到全部结点都处理完
        Polynominal tmp; // tmp存储当前结果
        Term *m = tmp.theList; // m指向tmp头结点
        Term *q = theList -> link; // q指向表头结点的后继结点
        while(q -> exp >= 0) { // 遍历当前单链表
            m = m -> InsertAfter((p -> coef) * (q -> coef), (p -> exp) + (q -> exp)); // 生成新结点插入m后
            q = q -> link;
        }
        result.PolyAdd(tmp); // 当前结果加到result上
        p = p -> link;
    }
    Term *q = theList -> link;
    while(q != NULL) { // 清空原数据
        theList -> link = q -> link;
        delete q;
        q = theList -> link;
    }
    q = theList;
    q = q -> InsertAfter(0, 0);
    PolyAdd(result); // result加到当前对象上
}
ostream & operator << (ostream &out, Polynominal &x)  
{  
    x.Output(out);  
    return out;  
}

istream & operator >> (istream &in, Polynominal &x)  
{  
    x.AddTerms(in);  
    return in;  
}

Polynominal & operator + (Polynominal &a, Polynominal &b)  
{  
    a.PolyAdd(b);  
    return a;  
}

Polynominal & operator * (Polynominal &a, Polynominal &b)  
{  
    a.PolyMul(b);  
    return a;  
}

int main()  
{
    Polynominal A,B;  
    cout << "Please input A:" << endl;  
    cin >> A;
    cout<<"A:\n"<<A;  
    cout << "Please input B:" << endl;  
    cin >> B;
    cout<<"B:\n"<<B;
    cout << "A + B = " << A + B << endl;
    cout << "A * B = " << A * B << endl;
    return 0;  
}  

在这里,多项式相乘函数做下比较。一种是:

void Polynominal::PolyMul(Polynominal& r)
{
    Polynominal result; // 存储结果
    Term *n = result.theList; // n指向result的头结点
    n = n -> InsertAfter(0, 0); // 将0, 0插入result的头结点之后
    Term *p = r.theList -> link; // p指向第一个要处理的结点
    while(p -> exp >= 0) { // 对r的单链表遍历,直到全部结点都处理完
        Polynominal tmp; // tmp存储当前结果
        Term *m = tmp.theList; // m指向tmp头结点
        Term *q = theList -> link; // q指向表头结点的后继结点
        while(q -> exp >= 0) { // 遍历当前单链表
            m = m -> InsertAfter((p -> coef) * (q -> coef), (p -> exp) + (q -> exp)); // 生成新结点插入m后
            q = q -> link;
        }
        result.PolyAdd(tmp); // 当前结果加到result上
        p = p -> link;
    }
    Term *q = theList -> link;
    while(q != NULL) { // 清空原数据
        theList -> link = q -> link;
        delete q;
        q = theList -> link;
    }
    q = theList;
    q = q -> InsertAfter(0, 0);
    PolyAdd(result); // result加到当前对象上
}
这是合理且正确的,我遇到了一个问题是:

void Polynominal::PolyMul(Polynominal& r)
 {
    Term* q,*p,*q1=theList,*m;
    q=q1->link;
    Polynominal t;
    m = t.theList->link;
    m = m->InsertAfter(0,0);
    int coef = 0;
    int exp = 0;
    q = r.theList->link; 
    while(q->exp>=0){    
        while(p->exp>=0){
            coef = p->coef * q->coef;
            exp = p->exp + q->exp;
            m = m->InsertAfter(coef,exp);
            p = p->link;
        }
        q1 =q->link;
        delete(q);
        q = q1->link;
    }
    p = t.theList->link;
    q = this->theList;
    q = q->InsertAfter(0,0);
    while(p->exp>=0){
    if(q->exp>=0){
        q->coef = p->coef;
        q->exp = p->exp;
        q1 = q->link;
        q = q->link;
    }
    else{
        q = q1;
        coef = p->coef;
        exp = p->exp;
        q = q->InsertAfter(coef,exp);
    }
    p = p->link;
    }
 }

一运行就崩溃啦,逻辑上的错误!对比两个函数实现代码,显然前者更清晰明了。后者逻辑上也是有问题的,比如多项式相乘之后指数相同的并没有合并之类的。但是我不知道可不可以再做改动然后达到相乘的效果?求指导!


当然?最上面的全部代码并不是正确的哈啊,在主函数中,输出A+B A*B结果必然是不对诶。这种低级错误恐怕也只有我会犯啦,执行完加法之后,多项式A已经变成了A+B,此A非彼A,所以再做乘法结果必然是不对的!那么怎么解决?傻逼也知道,不能把加法和乘法一次执行,应该区分开来,比如手动选择做加法还是乘法,然后根据输入来执行相应操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值