您的位置:首页 > 理论基础 > 数据结构算法

数据结构实习二2

2015-10-10 21:19 267 查看
实验要求:

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,所以再做乘法结果必然是不对的!那么怎么解决?傻逼也知道,不能把加法和乘法一次执行,应该区分开来,比如手动选择做加法还是乘法,然后根据输入来执行相应操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构