问题描述:
目的:使用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 &Factor, vector &Indice);
//表尾插入法动态生成链表
void CreateList_Tail(vector &Factor, vector &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的各项的指数(指数之间以空格分隔)
输出说明:
见测试数据样例
SAMPLE INPUT:
0
7.1 3.2 -22.3 9 5 -8
0 1 7 8 17 100
-3.2 22 -9
1 7 18
SAMPLEOUTPUT:
7.1+3.2x-22.3x7+9x8+5x17-8x100
-3.2x+22x7-9x18
7.1-0.3x7+9x8+5x17-9x18-8x^100
思路:
一道挺复杂的题目,题目所给的ADT表有些看不懂,写不出和题目相关的一系列函数,题目所给的大概就是一个带结点的链表中,系数和次数两个元素进行了捆绑,加减操作中只需要匹配相同的次数,对系数进行处理即可(无奈实力太弱,写不出来,只能偷鸡)写了一个普通的链表,然后通过对系数和次数分别建表进行操作,同一组的系数和次数在链表中的位置是相同的,可以通过这一点进行操作,一元多项式的加减的核心就是次数相同的项,其系数才会发生运算,所以在运算时只需要遍历第一个多项式中每一个次数能在第二个多项式中对应哪一个项目,系数进行运算即可。
AC代码:
#include <bits/stdc++.h>
using namespace std;
template<class ElemType>
struct LinkNode
{
ElemType data;
LinkNode<ElemType> *next;
LinkNode(LinkNode<ElemType> *ptr=NULL)
{
next=ptr;
}
LinkNode(const ElemType &item, LinkNode<ElemType> *ptr=NULL)
{
next=ptr;
data=item;
}
};
template <class ElemType>
class LinkList
{
private:
LinkNode<ElemType> *head;
LinkNode<ElemType> *tail;
void empty_push(ElemType num);
bool check_P(int n);
public:
LinkList()
{
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);
void searchfor();
int size();
void push_back(ElemType num);
void insert_head(ElemType num);
bool insert_back(int place, ElemType num);
LinkNode<ElemType> *get_front(LinkNode<ElemType> *p);
bool del(int i);
bool del_p(LinkNode<ElemType> *p);
ElemType at(int i);
void reverse(int m, int n);
LinkList<ElemType> *get_head()
{
return head;
}
LinkList<ElemType> *get_tail()
{
return tail;
}
void pick(LinkList<ElemType> &lis);
};
template <class ElemType>
int LinkList<ElemType>::size()
{
int len = 0;
if (head == NULL && tail == NULL)
return 0;
LinkNode<ElemType> *p;
p = head;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}
template <class ElemType>
void LinkList<ElemType>::empty_push(ElemType num)
{
head=new LinkNode<ElemType>;
tail=head;
head->data=num;
return;
}
template <class ElemType>
bool LinkList<ElemType>::check_P(int n)
{
if (0<=n&&n<size())
{
return true;
}
return false;
}
template <class ElemType>
void LinkList<ElemType>::reverse(int m,int 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;
}
template <class ElemType>
void LinkList<ElemType>::searchfor()
{
LinkNode<ElemType> *p = head;
while (p->next != NULL)
{
cout<<p->data;
cout<<"->";
p=p->next;
}
cout<<p->data<<endl;
return;
}
template <class ElemType>
void LinkList<ElemType>::push_back(ElemType num)
{
if(size()==0)
{
empty_push(num);
return;
}
LinkNode<ElemType>*p=new LinkNode<ElemType>;
p->data=num;
tail->next=p;
tail=p;
return;
}
template<class ElemType>
bool LinkList<ElemType>::del(int i)
{
return del_p(get_address(i));
}
template<class ElemType>
bool LinkList<ElemType>::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;
}
template <class ElemType>
void LinkList<ElemType>::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;
}
template <class ElemType>
bool LinkList<ElemType>::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;
}
template <class ElemType>
LinkNode<ElemType>*LinkList<ElemType>::get_address(int i)
{
LinkNode<ElemType> *p=head;
while(i--)
{
p=p->next;
}
return p;
}
template<class ElemType>
LinkNode<ElemType>*LinkList<ElemType>::get_front(LinkNode<ElemType> *p)
{
LinkNode<ElemType> *p1;
p1 = head;
while (p1->next != NULL)
{
if (p1->next == p)
return p1;
p1 = p1->next;
}
}
template<class ElemType>
ElemType LinkList<ElemType>::at(int i)
{
LinkNode<ElemType> *p = get_address(i);
return p->data;
}
template<class ElemType>
void LinkList<ElemType>::pick(LinkList<ElemType> &lis)
{
tail->next=lis.head;
tail=lis.tail;
return;
}
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 n;
cin>>n;
getchar();
string s1,s2,s3,s4;
getline(cin,s1);
getline(cin,s2);
getline(cin,s3);
getline(cin,s4);
list<double> A,B,C,D;
double num1=0.0;
int judge1=0,t1=0;
int j1=0;
int loop1=0;
for(unsigned i=0; i<s1.size(); i++)
{
if(s1[i]=='-')
{
loop1=1;
continue;
}
if(s1[i]==' ')
{
num1=num1/pow(10,t1);
if(loop1==1)
{
num1=0-num1;
loop1=0;
}
A.push_back(num1);
num1=0.0;
judge1=0,t1=0;
}
else if(s1[i]=='.')
{
judge1=1;
}
else
{
num1=num1*10+s1[i]-'0';
if(judge1==1)
{
t1++;
}
}
}
if(loop1==1)
{
num1=0-num1;
loop1=0;
}
num1=num1/pow(10,t1);
A.push_back(num1);
int num2=0;
for (unsigned i=0; i<s2.size(); i++)
{
if (s2[i]==' ')
{
B.push_back(num2);
num2=0;
}
else
{
num2=num2*10+s2[i]-'0';
}
}
B.push_back(num2);
output(A,B);
double num3=0.0;
int judge3=0,t3=0;
int j3=0;
int loop3=0;
for(unsigned i=0; i<s3.size(); i++)
{
if(s3[i]=='-')
{
loop3=1;
continue;
}
if(s3[i]==' ')
{
num3=num3/pow(10,t3);
if(loop3==1)
{
num3=0-num3;
loop3=0;
}
C.push_back(num3);
num3=0.0;
judge3=0,t3=0;
}
else if(s3[i]=='.')
{
judge3=1;
}
else
{
num3=num3*10+s3[i]-'0';
if(judge3==1)
{
t3++;
}
}
}
if(loop3==1)
{
num3=0-num3;
loop3=0;
}
num3=num3/pow(10,t3);
C.push_back(num3);
int num4=0;
for (unsigned i=0; i<s4.size(); i++)
{
if (s4[i]==' ')
{
D.push_back(num4);
num4=0;
}
else
{
num4=num4*10+s4[i]-'0';
}
}
D.push_back(num4);
output(C,D);
cout<<endl;
auto I1=A.begin(),I2=B.begin();
auto l3=C.begin(),l4=D.begin();
list<double> E, F;
while (I2 != B.end())
{
while (l4 != D.end() && *l4 < *I2)
{
if (!n)
E.push_back(*l3);
else
E.push_back(-*l3);
F.push_back(*l4);
l3++;
l4++;
}
if (*I2 == *l4)
{
if (n)
{
E.push_back(*I1-*l3);
F.push_back(*l4);
}
else
{
E.push_back(*l3+*I1);
F.push_back(*l4);
}
l3++;
l4++;
}
else
{
E.push_back(*I1);
F.push_back(*I2);
}
I1++;
I2++;
}
while (l4 != D.end())
{
if (!n)
E.push_back(*l3);
else
E.push_back(-*l3);
F.push_back(*l4);
l3++;
l4++;
}
output(E, F);
return 0;
}