多项式相加-C++实现

#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);

 


	
} 

猜你喜欢

转载自blog.csdn.net/cangzhexingxing/article/details/124725242