C++多项式运算类和引用计数的技巧

数据结构已经节课。和大家分享一下我自己的代码。http://download.youkuaiyun.com/detail/u011253734/7665207上面有

多项式运算类的头文件

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include<iostream>
#include<cstdio>
using namespace std;
struct LinkNode{
int coef;
int exp;
LinkNode* link;
LinkNode(LinkNode *ptr=NULL){link=ptr;}
LinkNode(const int & item1,const int & item2):coef(item1),exp(item2){}
friend ostream& operator<<(ostream&,LinkNode& );
};
class Cpolynomal
{   friend ostream& operator<<(ostream&, Cpolynomal&);//重载各种运算符
    friend istream& operator>>(istream&,Cpolynomal&);
    friend Cpolynomal operator + ( Cpolynomal&, Cpolynomal&);
    friend Cpolynomal operator - ( Cpolynomal&, Cpolynomal&);
    friend Cpolynomal operator * ( Cpolynomal&, Cpolynomal&);
    friend bool  operator == (Cpolynomal&,Cpolynomal&);
    friend bool  operator != (Cpolynomal&,Cpolynomal&);
    friend void  value(Cpolynomal&,int);//求值
public:
    Cpolynomal operator+=(Cpolynomal&);
    Cpolynomal operator-=(Cpolynomal&);
    Cpolynomal operator*=(Cpolynomal&);
    void derivation();//求导
    void multiplication( Cpolynomal h1, Cpolynomal h2);
    Cpolynomal(){first=new LinkNode(0,0);use=new size_t(1);}
    Cpolynomal(const int & item1,const int & item2){first = new LinkNode(item1,item2);}
    LinkNode * GetHead(){return first;}
    Cpolynomal(const Cpolynomal& obj):first(obj.first),use(obj.use){++*use;}
    Cpolynomal&operator=(const Cpolynomal&);
    ~Cpolynomal(){if(--*use==0){makeEmpty();}}
    void makeEmpty();
    void input();
    void output();
    void remove_0();
    int max_exp();
    bool all_zero();
    friend Cpolynomal operator-(Cpolynomal&);
private:
    LinkNode *first;
    size_t *use;
};

#endif

以下是实现文件。

use的作用是在于延迟析构。你可以看重载乘法的友元函数,自己思考思考他的作用。我会在最后解释。

#include"polynomial.h"
Cpolynomal&Cpolynomal::operator=(const Cpolynomal&rhs)
{++*rhs.use;
if(--*use==0){makeEmpty();}
first=rhs.first;
use=rhs.use;
return * this;
}

void  value( Cpolynomal& a, int n)
{   int val=0;
    int mid;
    LinkNode* ptr=a.GetHead()->link;
    while(ptr!=NULL)
    {        mid=1;
        for(int i=0;i<ptr->exp;i++)
            mid=mid*n;
    val=val+ptr->coef*mid;
    ptr=ptr->link;
    }
    cout<<"f("<<n<<")="<<val<<endl;
}
void Cpolynomal::derivation()
{
    LinkNode* ptr=first;
    ptr=ptr->link;
    while(ptr!=NULL)
    {ptr->coef=ptr->coef*ptr->exp;
     ptr->exp=ptr->exp-1;
    ptr=ptr->link;}
}
bool Cpolynomal::all_zero()
{ LinkNode *ptr=first;
  bool a=true;
  while(ptr!=NULL)
{if(ptr->coef!=0)a=false;
ptr=ptr->link;
 }
return a;

}
int Cpolynomal::max_exp()
{int max;
 LinkNode* p1=first;
      while(p1!=NULL)
   {
          max=p1->exp;
       p1=p1->link;
   }
return  max;
}
istream& operator>>(istream& is,Cpolynomal& h1)
{   int flag, sign, sum, x;
	char c;
	LinkNode * p =h1.first;
    while ( (c=getchar()) !='\n' )
	{
		if ( c == '<' )
	    {    sum = 0;
	         sign = 1;
	         flag = 1;
        }
		else if ( c =='-' )
             sign = -1;
		else if( c >='0'&& c <='9' )
		{    sum = sum*10 + c - '0';
        }
		else if ( c == ',' )
        {    if ( flag == 1 )
             {    x = sign * sum;
                  sum = 0;
                  flag = 2;
		  sign = 1;
             }
        }
		else if ( c == '>' )
        {    p->link = new LinkNode();
             p->link->coef = x;
             p->link->exp  = sign * sum;
             p = p->link;
             p->link = NULL;
             flag = 0;
        }
    }
   return is;
}
bool  operator == ( Cpolynomal& h1, Cpolynomal& h2)
{
    Cpolynomal c;
    c=h1-h2;
    return c.all_zero();
}
bool operator != ( Cpolynomal& h1, Cpolynomal& h2)
{
    return !(h1==h2);
}
Cpolynomal operator-(Cpolynomal&h1)
{LinkNode* p1=h1.first;
   int max;
   Cpolynomal c;
   LinkNode* p3=c.GetHead();
   int i;
   max=h1.max_exp();
   for(i=0;i<=max;i++)
   {
       p3->link=new LinkNode();
       p3=p3->link;
       p3->coef=0;
       p3->exp=i;
       p3->link=NULL;
   }
   for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
   {
       for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
       {
           if(p3->exp==p1->exp)
           {p3->coef=-p1->coef;break;}
        }
   }

    return c;
}
ostream& operator<<(ostream &os, Cpolynomal& a)
{   if(a.all_zero()) {cout<<0;return os;}
    LinkNode* ptr=a.GetHead();
    ptr=ptr->link;
    bool i=true;
    while(ptr!=NULL)
    {
     if(ptr->coef!=0)
    {
     if(ptr->coef>0)
        {if(i) {os<<ptr->coef<<"x^"<<ptr->exp;i=false;}
        else os<<'+'<<ptr->coef<<"x^"<<ptr->exp;
     }
    else{i=false;os<<ptr->coef<<"x^"<<ptr->exp;
    }}
    ptr=ptr->link;
    }
 return os;
}
Cpolynomal operator + (Cpolynomal& h1,Cpolynomal& h2)
{  LinkNode* p1=h1.first;
   LinkNode* p2=h2.first;
   int max;
   Cpolynomal c;
   LinkNode* p3=c.GetHead();
   int i;
 max=h1.max_exp()>h2.max_exp()? h1.max_exp():h2.max_exp();
   for(i=0;i<=max;i++)
   {
       p3->link=new LinkNode();
       p3=p3->link;
       p3->coef=0;
       p3->exp=i;
       p3->link=NULL;
   }
   for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
   {
       for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
       {
           if(p3->exp==p1->exp)
           {p3->coef=p3->coef+p1->coef;break;}
        }
   }

   int coef,exp;
     for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
   {   for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
       {
           if(p3->exp==p2->exp)
           {p3->coef=p3->coef+p2->coef;break;}
        }
   }
    return c;
}
Cpolynomal operator - (Cpolynomal& h1,Cpolynomal& h2)
{
   Cpolynomal c;
   c=-h2;
   c=h1+c;
   return c;
}
Cpolynomal operator * (Cpolynomal& h1, Cpolynomal& h2)
{  Cpolynomal c;
   LinkNode* p1=h1.GetHead();
   LinkNode* p2=h2.GetHead();
   int max1,max2;
      while(p1!=NULL)
   {
          max1=p1->exp;
       p1=p1->link;
   }
   while(p2!=NULL)
   {
          max2=p2->exp;
         p2=p2->link;
   }
   max1=max1+max2;
   LinkNode* p3=c.first;
   int i;
   for(i=0;i<=max1;i++)
   {
       p3->link=new LinkNode(0,i);
       p3=p3->link;
       p3->coef=0;
       p3->exp=i;
       p3->link=NULL;
   }
   int coef,exp;
   for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
     for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
   {   coef=p2->coef*(p1->coef);
       exp=p2->exp+p1->exp;
       for(p3=c.first->link;p3!=NULL;p3=p3->link)
       {
           if(p3->exp==exp)
           {p3->coef=p3->coef+coef;break;}
       }
   }
return  c;
}
Cpolynomal Cpolynomal::operator +=( Cpolynomal&h1)
{  Cpolynomal c;
    c=*this;
   c=c+h1;
   return c;
}
Cpolynomal Cpolynomal::operator -=( Cpolynomal&h1)
{
   *this=*this-h1;
   return *this;
}
Cpolynomal Cpolynomal::operator *=( Cpolynomal&h1)
{
   *this=*this*h1;
   return *this;
}
void Cpolynomal::makeEmpty()
{   LinkNode* q;
    while(first->link!=NULL)
    {
        q=first->link;
        first->link=q->link;
        delete q;
    }
    delete use;
} 
我单独把这个重载乘法函数拿出来看

Cpolynomal operator * (Cpolynomal& h1, Cpolynomal& h2)
{  Cpolynomal c;//临时变量c
   LinkNode* p1=h1.GetHead();
   LinkNode* p2=h2.GetHead();
   int max1,max2;
      while(p1!=NULL)
   {
          max1=p1->exp;
       p1=p1->link;
   }
   while(p2!=NULL)
   {
          max2=p2->exp;
         p2=p2->link;
   }
   max1=max1+max2;
   LinkNode* p3=c.first;
   int i;
   for(i=0;i<=max1;i++)
   {
       p3->link=new LinkNode(0,i);
       p3=p3->link;
       p3->coef=0;
       p3->exp=i;
       p3->link=NULL;
   }
   int coef,exp;
   for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
     for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
   {   coef=p2->coef*(p1->coef);
       exp=p2->exp+p1->exp;
       for(p3=c.first->link;p3!=NULL;p3=p3->link)
       {
           if(p3->exp==exp)
           {p3->coef=p3->coef+coef;break;}
       }
   }
return  c;//一系列操作后返回c,如果没有引用计数的话,c会拷贝给左值,然后自身析构函数,可想而知他会把他所连着的所有指针地址销毁,实际上返回的不指向任何东西
}

这时候引用计数就有用了。

use是指针,是为了共享use。

在构造函数中默认分配地址,并且赋其地址上的值为1。

拷贝构造的时候 拷贝地址,并且加一。

重载赋值运算符的时候,左操作数引用计数减一,右操作数的加一

析构函数则调用时减一,如果其值为0,说明只有一个变量在用,就直接析构。

有什么不对的地方还请大家指教。。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值