#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class dnode
{
public:
int ci,xi; //节点中储存了次数及对应的系数
dnode *prev;
dnode *next;
dnode(){next = this;prev = this; }
dnode(const int& c,const int&x): ci(c),xi(x){
next = this;
prev = this;}
void add(int x1){xi+=x1;}
friend bool tongmi(dnode d1,dnode d2);
};
bool tongmi(dnode d1,dnode d2){
return d1.ci==d2.ci;}
class List:public dnode{
private: dnode *first;
unsigned listsize;
public:
List():first(),listsize(0){first=new dnode(0,0);first->next=first;first->prev=first;};
void push_front(const int&ci,const int&xi);
void push_back(const int&ci,const int&xi);
void insert(int pos,const int&ci,const int&xi);
void shanchu(const dnode *p);
bool empty();
void pop_front();
void pop_back();
void erase(int pos);
void print();
void paixu();
friend List add(List&l1,List&l2);};
void List::push_back(const int&ci,const int&xi){
dnode *p=new dnode(ci,xi),*p1=first->prev;
p1->next=p;p->prev=p1;
p->next=first;first->prev=p;
listsize++;}
void List::push_front(const int&ci,const int&xi){
dnode *p=new dnode(ci,xi),*p1=first->next;
p1->prev=p;p->next=p1;
p->prev=first;first->next=p;
listsize++;}
void List::insert(int n,const int&ci,const int&xi){
dnode *p=new dnode(ci,xi),*p1=first,*p2;
int i;
for(i=0;i<n;i++){
p1=p1->next;}
p2=p1->next;
p1->next=p;p->prev=p1;
p2->prev=p;p->next=p1;
listsize++;}
void List::shanchu(const dnode *p){
dnode *p1=first,*p2,*p3;
int i=0;
while(i<=listsize){
p1=p1->next;
if(p1->ci==p->ci&&p1->xi==p->xi) break;
i++;}
p2=p1->prev;p3=p1->next;
p2->next=p3;
p3->prev=p2;
listsize--;
delete p1;
}
bool List::empty(){
return listsize==0;
}
void List::pop_front(){
dnode *p=first->next ;
first->next=p->next ;
p->next->prev=first;
listsize--;
delete p;
}
void List::pop_back(){
dnode *p=first->prev;
p->prev->next =first;
first->prev =p->prev ;
listsize--;
delete p;
}
void List::erase(int pos){
int i=0;
dnode *p=first;
while(i!=pos){
p=p->next ;
i++;}
p->prev->next =p->next ;
p->next->prev =p->prev ;
listsize--;
delete p;}
void List::paixu(){ //使链表内储存的多项式以幂的大小升序排序,用于提高合并多项式的效率
int minn,t1,t2,xi2;
dnode*minj;
dnode*temp;
dnode*p3,*p1,*p2;
for(p1=first->next;p1!=first;p1=p3->next){
minn=p1->ci;
minj=p1;
p3=p1;
for(p2=p1->next;p2!=first;p2=p2->next)
{
if(p2->ci<minn){
minn=p2->ci;
xi2=p2->xi;
minj=p2;}
}
if (minj!=p1) { //按照各储存的幂的大小升序排
t1=p1->ci;t2=p1->xi;
p1->ci=minn;p1->xi=xi2;
minj->ci=t1;minj->xi=t2;}}
}
void List::print(){
dnode *p=first->next;
while(p!=first->prev){
cout<<"("<<p->xi<<"x^"<<p->ci<<")"<<"+"; //按照标准格式输出
p=p->next;}
cout<<"("<<p->xi<<"x^"<<p->ci<<")"<<endl;
}
void run(char ss[],List &li1){
int i=0,k1=0,k2=0,ci=0,xi=0;
char ch=ss[0],temp=ch;
while(ss[i]!='#'){
ch=ss[i];
if(i==0){ //,用于提取首系数的数值
while(ch!='x'){ //考虑到首字符为‘-’的情况,提取系数
if(temp=='-'){i++;ch=ss[i];temp=' ';continue;}//若为‘-’,则跳到下一个字符,并坐好标记
xi=xi*10+ch-'0';
i++;ch=ss[i];}
if(temp==' ')xi=-xi;k1=1;} //有标记过,则取相反数 ,k1表示取到了系数
if(ch=='^'){ //若遇到表示幂的符号,则下个字符就是该次数的一部分
ci=0; //重置次数为0
ch=ss[++i];
while(ch!='+'&&ch!='-'&&ch!='#'){//本程序默认多项式以#结尾,不考虑输入有误的情况
ci=ci*10+ss[i]-'0'; //若还没遇到运算符或结束符,则一直提取次数
i++;
ch=ss[i];k2=1;}} //不考虑次数为负数的情况,k2用于标记取到了次数
if(k1==1&&k2==1){cout<<"本次取到的系数为"<<xi<<" 次数为"<<ci<<endl;k1=k2=0;li1.push_back(ci,xi);} //取到后k1,k1重置为0,将两个参数加入到对应链表
if(ch=='+'||ch=='-'){ //若遇到运算符,则下面的字符就是系数的一部分,开始取系数
xi=0;
temp=ch;
ch=ss[++i];
while(ch!='x'){
xi=xi*10+ss[i]-'0';
i++;
ch=ss[i];}
if(temp=='-')xi=-xi; //考虑系数为负数的情况
k1=1;i--;}
if(ss[i]=='#'){cout<<"该多项式存入完毕,退出----------------------------"<<endl;break; }//遇到#就立即退出
i++;}
}
List add(List&l1,List&l2) { //合并两个多项式的函数
List liss3;
int a,c1,c2; //c1储存l1当前节点的次数,c2储存l2当前节点的次数
bool k1,k2;
dnode*p1=l1.first->next,*p2=l2.first->next;
while(p1!=l1.first&&p2!=l2.first){
c1=p1->ci;c2=p2->ci;
cout<<"l1当前取出的次数为"<<c1<<" l2当前取出的次数"<<c2<<endl; //用于测试,看是否输出正确
if(c1==c2){ //若次数相等,则将对应系数相加,存入liss3
a=p1->xi+p2->xi;
liss3.push_back(p1->ci,a);
p1=p1->next;p2=p2->next;
if(p1==l1.first||p2==l2.first){ break;} //若一个多项式已经合并完了,则退出循环
continue;}
if(c1>c2){ //若c1大于c2
while(c1>c2&&p2!=l2.first&&p1!=l1.first){ //把li2的多项式存入liss3,直到li1当前多项式次数小于等于li2当前多项式次数
liss3.push_back(p2->ci,p2->xi);
p2=p2->next;
c2=p2->ci;
} }
if(c1<c2){
while(c1<c2&&p1!=l1.first&&p2!=l2.first){
liss3.push_back(p1->ci,p1->xi);
p1=p1->next;
c1=p1->ci;}
}
}
while(p1!=l1.first){ //若li1的多项式还没合并完,则直接将多项式存入liss3
liss3.push_back(p1->ci,p1->xi);
p1=p1->next;
}
while(p2!=l2.first){
liss3.push_back(p2->ci,p2->xi);
p2=p2->next;
}
cout<<"两多项式合并结果为------------------------------------------" <<endl;
liss3.print();
}
int main(){
char ss1[]="-2x^223-4x^3+6x^1+67x^9#"; //多项式的输入以#结束,不考虑次数为负数的情况
char ss2[]="-3x^3+4x^1+8x^2-32x^9-22x^5+55x^88#";
List li1,li2,li3;
run(ss1,li1);
run(ss2,li2);
li1.paixu();
li2.paixu();
li1.print();
li2.print();
add(li1,li2);
}
多项式相加-C++实现
最新推荐文章于 2023-03-26 22:55:36 发布