巨型整数运算符重载实现部分

来源:互联网 发布:淘宝推荐系统 研究 编辑:程序博客网 时间:2024/05/01 11:27

巨型整型运算重载--实现部分(.cpp)

关键词HugeInt    运算符重载   

#define MAXLEN 1000//定义巨型数据的最大长度
#include < conio.h >
//*----------------------------各构造函数的实现[begin]---------------------------*//

//------------------HugeInt类构造函数(不带参数 使用默认值0初始化)---------------//
/*
函数名:HugeInt类构造函数
传入参数:字符指针
功能:实现使用默认值0初始化类对象
*/
HugeInt::HugeInt()
{
//初始化一带头结点的空双向循环链表//
RightEnd=0;
node *temp=new node;
temp->left=temp;
temp->right=temp;
head=temp;
head->data=0;
RightEnd=head;
n=0;
}

//------------------HugeInt类构造函数(参数类型 字符串)----------------------------//
/*
函数名:HugeInt类构造函数
传入参数:字符指针
功能:实现使用字符串初始化类对象
*/
HugeInt::HugeInt(char *data)
{
//初始化一带头结点的空双向循环链表//
RightEnd=0;
node *temp=new node;
temp->left=temp;
temp->right=temp;
head=temp;
head->data=0;
RightEnd=head;
n=0;

//接收传入的参数
char *tempdata=new char[strlen(data)+1];
strcpy(tempdata,data);

//如果输入的数据串合法 则将其分段并存储在链表中//
//说明:比如字符串"000100000632000"插入到链表中各结点为0,1000,63,2000//
if(IsRight(data))
{ //根据符号设置头结点值 负数为1 正数为0//
if(data[0]=='-')
{head->data=1;}
else
{head->data=0;}

//取输入数据串的绝对值
char *newdata=new char[strlen(tempdata)+1];
strncpy(newdata,abs(tempdata),strlen(newdata));

short int len=strlen(newdata);//len 数据串的位数 不包括符号

//当数据的位数大于分段的单位4时 以4位一组作为结点循环插入到链表//
while(len>=4)
{
char temp[5]={0};

strncpy(temp,newdata+len-4,4);//从数据串尾部开始 截取4位长


Insert(atoi(temp));// atoi() 将数据转为整型后插入 每次都是在头结点后插入


len=len-4;
}//end while

//执行上述循环后 将剩下的位数做为一个结点插入
if(len>0&&len<4)
{
char temp[4]={0};

strncpy(temp,newdata,len);

Insert(atoi(temp));

}//end if

}//end if
else//数据不合法的情况 默认值为0
{
Insert(0);
}


}
//------------------HugeInt类构造函数(参数类型 长整型)----------------------------//
/*
函数名:HugeInt类构造函数
传入参数:长整型
功能:实现使用长整型初始化类对象
*/
HugeInt::HugeInt(const long k)
{
//定义一空的双向循环链表//
RightEnd=0;
node *temp=new node;
temp->left=temp;
temp->right=temp;
head=temp;
RightEnd=head;
head->data=0;
n=0;
//根据符号设置头结点值 负数为1 正数为0//
if(k<0)
{head->data=1;}
else
{head->data=0;}

//接收传入的参数并转为字符串
char* str=new char[sizeof(k)+1];
itoa(k,str,10);

//如果输入的数据串合法 则将其分段并存储在链表中//
if(IsRight(str))
{
//取数据串的绝对值
char *newdata=new char[strlen(str)+1];
strncpy(newdata,abs(str),strlen(newdata));
short int len=strlen(newdata);

//当数据的位数大于分段的单位4时 以4位一组作为结点循环插入到链表//
while(len>=4)
{ char temp[5]={0};
strncpy(temp,newdata+len-4,4);//从数据串尾部开始 截取4位
Insert(atoi(temp));// atoi() 将数据转为整型后插入 每次都是在头结点后插入
len=len-4;
}//end while

//执行上述循环后 将剩下的位数做为一个结点插入
if(len>0&&len<4)
{ char temp[4]={0};
strncpy(temp,newdata,len);//从数据串头部开始 截取len位
Insert(atoi(temp));
}//end if

}//end if
else//数据不合法的情况 默认值为0
{
Insert(0);
}

}
//------------------HugeInt类拷贝构造函数----------------------------//
/*
函数名:HugeInt类拷贝构造函数
传入参数:类对象的引用
功能:实现使用已知类对象初始化类
*/
HugeInt::HugeInt(HugeInt& h)
{ //定义一空的双向循环链表//

n=0;
RightEnd=0;
node *temp=new node;
temp->left=temp;
temp->right=temp;
head=temp;

head->data=h.GetHeadNode()->data;//设置头结点
RightEnd=head;//设置尾结点

//获得链表各结点值
for(temp=h.RightEnd;temp!=h.GetHeadNode();temp=temp->left)
{
Insert(temp->data);
}

}
/*----------------------------HugeInt类析构函数---------------------------*/
HugeInt::~HugeInt()
{

DelList();//删除所有结点

delete head;//删除头结点

}
/*----------------------------各构造函数的实现[end]---------------------------*/

/*----------------------------各成员函数的实现[begin]---------------------------*/

//------------------插入结点(HugeInt类成员函数)----------------------------//
/*
函数名:Insert
参数: const short int x(常短整型)
返回值:this对象
功能:实现在双链表头结点(head)后插入新结点
*/
HugeInt& HugeInt::Insert(const short int x)
{//在头结点后插入新结点

node *temp=new node;
temp->data=x;
temp->left=head;
temp->right=head->right;
head->right->left=temp;
head->right=temp;
n++;

//因每次都是在头结点后插入新结点 故只需移动一次尾结点 即当n==1时
if(n==1)
{RightEnd=RightEnd->right;}

return *this;
}
//------------------删除所有结点(HugeInt类成员函数)----------------------------//
void HugeInt::DelList()
{
while(n!=0)
{node *temp=new node;
temp=GetEndNode();
RightEnd=RightEnd->left;

temp->right->left=temp->left;
temp->left->right=temp->right;
delete temp;
n--;
}
}
//------------------求数据串绝对值(重载abs函数)---------------------------//
/*
函数名:abs
传入参数:char *data (字符指针)
返回值:字符指针
功能:返回数据串的绝对值(如"-563256223354" 返回"563256223354")
*/
char* HugeInt::abs(char *data)
{
char* newdata=new char[strlen(data)+1];
if(data[0]=='-')
{return strncpy(newdata,data+1,strlen(newdata)-1);}//返回不带负号的数据串
else
return strncpy(newdata,data,strlen(newdata));

}
//-----------------检验数据合法性(HugeInt类成员函数)----------------------------------//
/*
函数名:IsRight
传入参数:char *data (字符指针)
返回值:bool型(true 合法.false非法)
功能:判断输入的数据是否合法
说明:在本程序中所谓的合法是指输入的字符串中的每个字符只能为数字(0~9)
允许首字符为"+"与"-"(正负号)
比如合法的字符串: "+0563256","-55115100016","454512053566"等
非法的字符串:"--5632266","df5df12515","dfgjkr"等
*/
bool HugeInt::IsRight(char *data)
{
bool flag=false;//定义是否合法标志 做为返回值

if(strlen(data)>MAXLEN)//字符串长度超过定义的最大长度
{ cout<<"字符串长度超过定义的最大长度/n";
return flag;

}//end if

else//字符串长度合法的情况
{
if((data[0]=='-'||data[0]=='+')&&strlen(data)!=1)//判断首字符
{flag=true;}

if(strlen(data)==1&&data[0]-48>=0&&data[0]-48<=9)//如果为单字符
{flag=true;}


//如果flag==false 则从第一位开始判断 否则
//从字符串第二位开始 判断字符是否为数字字符//
short int i=flag;
while(i < strlen(data))
{
if(data[i]-48>=0&&data[i]-48<=9)
{flag=true;}
else
{flag=false;break;}//只要发现一个非法字符 则退出循环
i++;

}//end while
if(!flag)
cout<<"[错误]数据不合法[数据不合法的情况 本程序返回默认值0]/n";
return flag;
}//end else

}
//------------------------输出结点(HugeInt类成员函数)------------------------------//
/*
函数名:PrintList
参数:无
返回值:void
功能:实现链表的输出
说明:如数据1265300065632存储在链表中 各结点为1,2653,6,5632
显然不能简单的将结点直接输出 要补上相应的0
*/
void HugeInt::PrintList()const
{ node *current=new node;
if (head->data==1)//数据串为负数的情况
{


if(head->right->data!=0)//如果第一个结点不为0则输出"-"与该结点数据
{cout<<"-"<< head-> right->data;}
else//如果第一个结点为0
{
if(head->right->right==head)//如果只有一个结点(也就是0)
{cout<< head->right->data;}//输出0
else//不止一个结点 需要输出负号
cout<<"-";
}

}//数据串为负数的情况结束

else//数据串为正数的情况
{
//同样也是先判断第一个结点的输出
if((head->right->data!=0))
{cout<<head->right->data;}
else
if(head->right->right==head)//如果只有一个结点(也就是0)
{cout<<head->right->data;}//输出0

}
bool f=false;//标识在当前结点前是否已有其他结点输出(也就是当前结点是否是数据串的最高位)
//f=false 表示当前结点是最高位
//从第二个结点开始循环输出 补上相应个数的零
for(current=head->right->right;current!=head;current=current->right)
{
if(current->left->data!=0||f)//如果当前结点的左结点不为零或当前结点不是最高位的情况
{ f=true;

//根据结点值补上相应个数的0
if(current->data<=9)//小于9的情况
{cout<<"000"<<current->data;}
else//大于9的情况
{
if(current->data>9 && current->data<=99)
{cout<<"00"<<current->data;}
else
{
if(current->data>99 && current->data<=999)
{cout<<"0"<<current->data;}

if(current->data>999 && current->data<=9999)
{ cout<<current->data;}
}
}//补零操作完成


}

else//当前结点左结点为零并且当前结点是最高位
{
if(current->data!=0)//该结点值不为零则输出
cout<<current->data;
else//该结点值为零 则只有在链表结点个数为1的情况下输出(也就是输出0了)
if(current->right==head)
cout<<current->data;
}

}//for循环结束

}
//*----------------------------各成员函数的实现[end]---------------------------*//

//*----------------------------各运算符重载函数的实现[begin]-------------------*//

//---------------------------------[>]---------------------------------------------------//

//[1]-----------------------重载>(大于 巨型与巨型)-------------------------------//
/*重载运算符:>
参数:类对象引用
返回值:bool型
*/
bool operator>(HugeInt &m,HugeInt &n)
{

if(m.GetHeadNode()->data==1&&n.GetHeadNode()->data==0)//如果m为负 n为正则m<n 返回false
{return false;}

else//else 1
{
if(m.GetHeadNode()->data==0&&n.GetHeadNode()->data==1)//如果m为正 n为负
{
if(m.IsZero()&&n.IsZero())//m与n等于零的情况
return false;
else//其余情况返回true
return true;


}
else// else 2
{

if((m.GetHeadNode()->data+n.GetHeadNode()->data)==0)//两数同正
{ bool flag=false;//标识返回值

//将m,n结点数置成相同
int len=abs(m.GetN()-n.GetN());
if(m.GetN()>n.GetN())
{ for(int i=0;i<len;i++)
n.Insert(0);
}
if(m.GetN()<n.GetN())
{for(int i=0;i<len;i++)
m.Insert(0);
}

//定义两个结点分别指向m,n的第一个结点
node* mcurrent=new node;
node* ncurrent=new node;
mcurrent=m.GetHeadNode()->right;
ncurrent=n.GetHeadNode()->right;

//从第一个结点开始比较m,n的对应结点
while(mcurrent!=m.GetHeadNode())
{
if(mcurrent->data>ncurrent->data)//如果m的当前结点值大于n则退出循环 返回true
{flag=true;break;}
else
if(mcurrent->data<ncurrent->data)//如果m的当前结点值小于n则退出循环 返回true
{flag=false;break;}
else//当前值相等的情况 继续下一结点比较
{mcurrent=mcurrent->right;ncurrent=ncurrent->right;}

}
return flag;
}//两数同为正的情况结束

else//两数同为负的情况 进行两数绝对值的比较
{
return abs(n)>abs(m);

}

}//end else 2

}//end else 1


}

//[2]-----------------------重载>(大于 巨型与长整型)-----------------------------//
bool operator>(HugeInt &m,const long int &n)
{ //先进行类型转换 再比较
return m>HugeInt(n);
}
//[3]-----------------------重载>(大于 长整型与巨型)-----------------------------//
bool operator>(const long int &m,HugeInt &n)
{ //先进行类型转换 再比较
return HugeInt(m)>n;
}
//[4]-----------------------重载>(大于 巨型与字符型)-----------------------------//
bool operator>(HugeInt &m, char* n)
{ //先进行类型转换 再比较
return m>HugeInt(n);
}
//[5]-----------------------重载>(大于 字符型与巨型)--------------------------------//
bool operator>( char* m,HugeInt &n)
{ //先进行类型转换 再比较
return HugeInt(m)>n;
}


//------------------------------[<]-------------------------------------------------------//

//[1]---------------------重载<(小于 巨型与字符型比较)--------------------------------//
bool operator<(HugeInt &m, char* n)
{ //先进行类型转换 再根据已重载的运算符(>)进行比较
HugeInt temp(n);
return (m>temp||m==temp)?false:true;
}
//[2]---------------------重载<(小于 字符型与巨型比较)-------------------------------//
bool operator<( char* m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>)进行比较
HugeInt temp(m);
return (temp>n||temp==n)?false:true;
}
//[3]---------------------重载<(小于 巨型与长整型比较)-------------------------------//
bool operator<(HugeInt &m,const long int &n)
{ //先进行类型转换 再根据已重载的运算符(>)进行比较
HugeInt temp(n);
return (m>temp||m==temp)?false:true;
}
//[4]---------------------重载<(小于 长整型与巨型比较)------------------------------//
bool operator<(const long int &m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>)进行比较
HugeInt temp(m);
return (temp>n||temp==n)?false:true;
}
//[5]---------------------重载<(小于 巨型与巨型比较)--------------------------------//
bool operator<(HugeInt &m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>)进行比较
return (m>n||m==n)?false:true;
}


//-----------------------------[==]-----------------------------------------------------//

//[1]-------------------重载==(等于 巨型与巨型比较)--------------------------------//
/*重载运算符:==
参数:类对象引用
返回值:bool型
*/
bool operator==(HugeInt &m,HugeInt &n)
{

bool flag=false;

//如果m,n不为零并且异号 返回false
if((m.GetHeadNode()->data!=n.GetHeadNode()->data)&&!m.IsZero()&&!n.IsZero())
{flag=false;}

else
{
//将m,n结点数置成相同
int len=abs(m.GetN()-n.GetN());
if(m.GetN()>n.GetN())
{ for(int i=0;i<len;i++)
n.Insert(0);
}
if(m.GetN()<n.GetN())
{for(int i=0;i<len;i++)
m.Insert(0);
}

//定义两个结点分别指向m,n的第一个结点
node* mcurrent=new node;
node* ncurrent=new node;
mcurrent=m.GetHeadNode()->right;
ncurrent=n.GetHeadNode()->right;

while(mcurrent!=m.GetHeadNode())//从第一个结点开始对应比较
{
if(mcurrent->data!=ncurrent->data)//如果发现不等则退出循环
{flag=false;break;}
else//其他情况继续进行下一结点比较
{flag=true;mcurrent=mcurrent->right;ncurrent=ncurrent->right;}


}//end while


}//end else
return flag;

}
//[2]-------------------重载==(等于 巨型与长整型比较)--------------------------------//
bool operator==(HugeInt &m,const long int &n)
{ //先进行类型转换 再比较
return m==HugeInt(n);
}
//[3]-------------------重载==(等于 长整型与巨型比较)--------------------------------//
bool operator==(const long int &m,HugeInt &n)
{ //先进行类型转换 再比较
return HugeInt(m)==n;
}
//[4]-------------------重载==(等于 巨型与字符型比较)--------------------------------//
bool operator==(HugeInt &m,char* n)
{ //先进行类型转换 再比较
return m==HugeInt(n);
}
//[5]-------------------重载==(等于 字符型与巨型比较)--------------------------------//
bool operator==(char* m,HugeInt &n)
{ //先进行类型转换 再比较
return HugeInt(m)==n;
}


//--------------------------------[>=]----------------------------------------------------//

//[1]-------------------------重载>=(大于等于 巨型与字符型)------------------------------//

bool operator>=(HugeInt &m,char* n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(n);
return (m>temp||m==temp);

}
//[2]-------------------------重载>=(大于等于 字符型与巨型)-----------------------------//
bool operator>=(char* m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(m);
return (temp>n||temp==n);

}
//[3]-------------------------重载>=(大于等于 巨型与长整型)-----------------------------//

bool operator>=(HugeInt &m,const long int &n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(n);
return (m>temp||m==temp);

}
//[4]-------------------------重载>=(大于等于 长整型与巨型)-----------------------------------//
bool operator>=(const long int &m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(m);
return (temp>n||temp==n);

}
//[5]-------------------------重载>=(大于等于 巨型与巨型)-----------------------------------//
bool operator>=(HugeInt &m,HugeInt &n)
{ //根据已重载的运算符(>,==)进行比较
return (m>n||m==n);

}


//--------------------------------[<=]---------------------------------------------------//

//[1]-------------------------重载<=(小于等于 字符型与巨型)------------------------//
bool operator<=(char* m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(m);
return (temp<n||temp==n);

}
//[2]-------------------------重载<=(小于等于 巨型与字符型)------------------------//
bool operator<=(HugeInt &m,char* n)
{ //先进行类型转换 再根据已重载的运算符(<,==)进行比较
HugeInt temp(n);
return (m<temp||m==temp);

}
//[3]-------------------------重载<=(小于等于 长整型与巨型)-----------------------//
bool operator<=(const long int &m,HugeInt &n)
{ //先进行类型转换 再根据已重载的运算符(>,==)进行比较
HugeInt temp(m);
return (temp<n||temp==n);

}
//[4]-------------------------重载<=(小于等于 巨型与长整型)----------------------//
bool operator<=(HugeInt &m,const long int &n)
{ //先进行类型转换 再根据已重载的运算符(<,==)进行比较
HugeInt temp(n);
return (m<temp||m==temp);

}
//[5]-------------------------重载<=(小于等于 巨型与巨型)-----------------------//
bool operator<=(HugeInt &m,HugeInt &n)
{ //根据已重载的运算符(<,==)进行比较
return (m<n||m==n);
}


//-----------------------------[!=]-----------------------------------------------//

//[1]-------------------------重载!=(不等于 字符型与巨型)-----------------------//
bool operator!=(char* m,HugeInt &n)
{ //先进行类型转换 根据已重载的运算符(!,==)进行比较
return (!(HugeInt(m)==n));

}
//[2]-------------------------重载!=(不等于 巨型与字符型)------------------------//
bool operator!=(HugeInt &m,char* n)
{ //先进行类型转换 根据已重载的运算符(!,==)进行比较
return (!(m==HugeInt(n)));

}
//[3]-------------------------重载!=(不等于 长整型与巨型)-------------------------//
bool operator!=(const long int m,HugeInt &n)
{ //先进行类型转换 根据已重载的运算符(!,==)进行比较
return (!(HugeInt(m)==n));

}
//[4]-------------------------重载!=(不等于 巨型与长整型)------------------------//
bool operator!=(HugeInt &m,const long int n)
{ //先进行类型转换 根据已重载的运算符(!,==)进行比较
return (!(m==HugeInt(n)));

}
//[5]-------------------------重载!=(不等于 巨型与巨型)--------------------------//
bool operator!=(HugeInt &m,HugeInt &n)
{ // 根据已重载的运算符(!,==)进行比较
return (!(m==n));

}

//--------------------------重载<<(输出)--------------------------------------//
ostream &operator<<(ostream &out,HugeInt &m)
{ m.PrintList();//调用PrintList()函数输出各结点
return out;
}

//-----------------------------------[-]---------------------------------------------//

//[1]-------------------------重载-(减法 字符型与巨型)----------------------------//
HugeInt operator -(char* minuend,HugeInt& subtrahend)
{ //先进行类型转换 根据已重载的运算符(-)进行运算
return HugeInt(minuend)-subtrahend;
}

//[2]-------------------------重载-(减法 巨型与字符型)---------------------------//
HugeInt operator -(HugeInt& minuend,char* subtrahend)
{ //先进行类型转换 根据已重载的运算符(-)进行运算
return minuend-HugeInt(subtrahend);
}
//[3]-------------------------重载-(减法 长整型与巨型)---------------------------//
HugeInt operator -(const long int& minuend,HugeInt& subtrahend)
{ //先进行类型转换 根据已重载的运算符(-)进行运算
return HugeInt(minuend)-subtrahend;
}
//[4]-------------------------重载-(减法 巨型与长整型)--------------------------//
HugeInt operator -(HugeInt& minuend,const long int& subtrahend)
{ //先进行类型转换 根据已重载的运算符(-)进行运算
return minuend-HugeInt(subtrahend);
}
//[5]-------------------------重载-(减法 巨型与巨型)---------------------------//
/*重载运算符:-
参数:类对象引用(minuend 被减数,subtrahend 减数)
返回值:类对象
*/
HugeInt operator -(HugeInt& minuend,HugeInt& subtrahend)
{
if((minuend.GetHeadNode()->data+subtrahend.GetHeadNode()->data)==0)//同为正数的情况
{
if(minuend>=subtrahend)//被减数大于减数
{
//新建结点并指向两数尾结点
node* curmin=new node;
curmin=minuend.GetEndNode();
node* cursub=new node;
cursub=subtrahend.GetEndNode();

//将减数与被减数结点数置成相同
int len=abs(minuend.GetN()-subtrahend.GetN());
if(minuend.GetN()>subtrahend.GetN())
{
for(int i=0;i<len;i++)
subtrahend.Insert(0);
}
if(minuend.GetN()<subtrahend.GetN())
{
for(int i=0;i<len;i++)
minuend.Insert(0);
}

//做两正数的减操作//
HugeInt sub;//存放相减结果
short int borrow=0;//标识借位
while(curmin!=minuend.GetHeadNode())//从尾结点开始两结点数据做减操作
{
if(curmin->data-borrow-cursub->data>=0)//如果被减数够减
{
sub.Insert(curmin->data-borrow-cursub->data);//将相减结果存入结果链表中
borrow=0;//标识借位为0(没有借位)

}
else//有借位情况
{
//相减结果为负,将结果加上10000(一个结点四位)并存入结果链表中//
sub.Insert(curmin->data-borrow-cursub->data+10000);//
borrow=1;//标识借位为1(表示借值10000)
}

curmin=curmin->left;//被减数指向前一结点
cursub=cursub->left;//减数指向前一结点

}//while结束
return sub;

}

else//被减数小于减数
{
return -(abs(subtrahend)-abs(minuend));//返回绝对值差的相反数
}



}//if结束(同为正数的情况结束)

else
{
if((minuend.GetHeadNode()->data+subtrahend.GetHeadNode()->data)==2)//如果同为负数
{
if(abs(minuend)>abs(subtrahend))//被减数绝对值大于减数绝对值
{
return -(abs(minuend)-abs(subtrahend));

}
else
{
return abs(subtrahend)-abs(minuend);
}

}
else
{ //一正一负的情况[转为正数加法]

if(minuend>subtrahend)
{
return (abs(minuend)+abs(subtrahend));
}
else
{
return -(abs(subtrahend)+abs(minuend));
}


}//一正一负的情况结束

}//end else



}

//--------------重载abs(求绝对值)---------------------------------------------//
/*重载运算符:abs
参数:类对象
返回值:类对象
*/
HugeInt abs(HugeInt h)
{
h.SetHeadData(0);//设置头结点数据为0(表示正数)
return h;

}
//---------------重载-(求反)----------------------------------------------------//
/*重载运算符:-
参数:HugeInt对象
返回值:HugeInt对象
*/
HugeInt operator-(HugeInt h)
{

(h.GetHeadNode()->data==0)?h.SetHeadData(1):h.SetHeadData(0);//将数据符号置反

return h;

}

//------------------------------------[+]---------------------------------------------//

//[1]-----------------重载+(加法 巨型与巨型)-------------------------------//
HugeInt operator +(HugeInt& addend,HugeInt& augend)
{

if((addend.GetHeadNode()->data+augend.GetHeadNode()->data)==0)//同为正数的情况

{

if(addend.GetN()>=augend.GetN())//如果被加数的结点数大于加数
{
//新建两个结点分别指向被加数与加数尾结点
node* curadd=new node;
curadd=addend.GetEndNode();
node* curaug=new node;
curaug=augend.GetEndNode();

HugeInt sum;//标识和
int carry=0;//标识进位

//从加数尾结点开始循环 让每个结点与被加数的对应结点相加
//比如被加数1,2345,6789,加数:2345,6789
while(curaug!=augend.GetHeadNode())
{

sum.Insert((curadd->data+curaug->data+carry)%10000);//sum对应结点的值

carry=(curadd->data+curaug->data+carry)/10000;//设置进位

curaug=curaug->left;
curadd=curadd->left;
}
//处理剩下的被加数结点 如上述两个数 对应结点相加后还剩结点1
while(curadd!=addend.GetHeadNode())
{
sum.Insert((curadd->data+carry)%10000);

carry=(curadd->data+carry)/10000;
curadd=curadd->left;

}
if(carry!=0)//全部加完还有进位
{sum.Insert(carry); }
return sum;

}
else
{
return augend+addend;//执行加数+被加数
}


}//同为正数的情况结束
else
{ if((addend.GetHeadNode()->data+augend.GetHeadNode()->data)==2)//如果同为负数

{
return -(abs(addend)+abs(augend));

}
else//[一正一负情况(转为减法处理)]
{ if(addend>augend)
return addend-abs(augend);
else
return augend-abs(addend);

}

}
}
//[2]-----------------重载+(加法 巨型与长整型)------------------------------------------------------//
HugeInt operator +(HugeInt& addend,const long int& augend)
{ //先进行类型转换 再根据已重载的运算符(+)进行运算
return HugeInt(augend)+addend;

}
//[3]-----------------重载+(加法 长整型与巨型)------------------------------------------------------//
HugeInt operator +(const long int& addend,HugeInt& augend)
{ //先进行类型转换 再根据已重载的运算符(+)进行运算
return HugeInt(addend)+augend;

}
//[4]-----------------重载+(加法 巨型与字符型)------------------------------------------------------//
HugeInt operator +(HugeInt& addend,char* augend)
{ //先进行类型转换 再根据已重载的运算符(+)进行运算
return HugeInt(augend)+addend;

}
//[5]-----------------重载+(加法 字符型与巨型)------------------------------------------------------//
HugeInt operator +(char* addend,HugeInt& augend)
{ //先进行类型转换 再根据已重载的运算符(+)进行运算
return HugeInt(addend)+augend;

}

//---------------------------------[+=]-------------------------------------------------//

//[1]-----------------------------重载+=()------------------------------------------//
HugeInt& HugeInt::operator +=(HugeInt& augend)
{ //根据已重载的运算符(+,=)进行运算
*this=*this+augend;
return *this;
}
//[2]-----------------------------重载+=()------------------------------------------//
HugeInt& HugeInt::operator +=(const long int& augend)
{ //先进行类型转换 根据已重载的运算符(+,=)进行运算
*this=*this+HugeInt(augend);
return *this;
}
//[3]-----------------------------重载+=()------------------------------------------//
HugeInt& HugeInt::operator +=(char* augend)
{ //先进行类型转换 根据已重载的运算符(+,=)进行运算
*this=*this+HugeInt(augend);
return *this;
}

//--------------------------------------[-=]------------------------------------------//

//[1]-----------------------------重载-=()------------------------------------------//
HugeInt& HugeInt::operator -=(HugeInt& subtrahend)
{ //根据已重载的运算符(-,=)进行运算
*this=*this-subtrahend;
return *this;
}
//[2]-----------------------------重载-=()------------------------------------------//
HugeInt& HugeInt::operator -=(const long int& subtrahend)
{ //先进行类型转换 根据已重载的运算符(-,=)进行运算
*this=*this-HugeInt(subtrahend);
return *this;
}
//[3]-----------------------------重载-=()------------------------------------------//
HugeInt& HugeInt::operator -=(char* subtrahend)
{ //先进行类型转换 根据已重载的运算符(-,=)进行运算
*this=*this-HugeInt(subtrahend);
return *this;
}

//------------------------------------[=]---------------------------------------------//

//[1]-----------------------------重载=()------------------------------------------//
HugeInt& HugeInt::operator =(const long int& k)
{ *this=HugeInt(k);//先进行类型转换,再调用拷贝构造函数 实现对象赋值

return *this;
}
//[2]-----------------------------重载=()------------------------------------------//
HugeInt& HugeInt::operator =(char* k)
{ *this=HugeInt(k);//先进行类型转换,再调用拷贝构造函数 实现对象赋值

return *this;
}

//[3]-----------------------------重载=()------------------------------------------//
/*
说明:对象与对象之间本是可以直接赋值 但考虑到有指针类型成员的存在
所以需要重载=与拷贝构造函数
*/
HugeInt& HugeInt::operator =(HugeInt& h)
{
HugeInt newh(h);
DelList();//删除已有结点

//循环执行值拷贝
node *current=new node;
current=newh.GetEndNode();
while(current!=newh.GetHeadNode())
{
Insert(current->data);
current=current->left;

}

SetHeadData(newh.GetHeadNode()->data);//设置头结点
return *this;
}


//------------------------++(前++)-------------------------------//
HugeInt& HugeInt::operator ++()
{ //当前对象加1后返回当前对象
*this+=1;
return *this;

}

//------------------------++(后++)-------------------------------//
HugeInt HugeInt::operator ++(int)
{
HugeInt temp=*this;//建立临时对象保存当前对象值
*this+=1;//当前对象值加1
return temp;//返回临时对象

}

//---------------------------(前--)-------------------------------//
HugeInt& HugeInt::operator --()
{ //当前对象减1后返回当前对象
*this-=1;
return *this;

}

//--------------------------(后--)-------------------------------//
HugeInt HugeInt::operator --(int)
{
HugeInt temp=*this;//建立临时对象保存当前对象值
*this-=1;//当前对象值减1
return temp;//返回临时对象

}

//---------------------------------[*=]----------------------------------------------//

//[1]-----------------------乘等于(巨型与字符型)----------------------------------//
HugeInt& HugeInt::operator *=(char* faciend)
{ //先进行类型转换 再根据已重载的运算符(*,=)进行运算
*this=*this*HugeInt(faciend);
return *this;
}
//[2]-----------------------乘等于(巨型与长整型)----------------------------------//
HugeInt& HugeInt::operator *=(const long int& faciend)
{ //先进行类型转换 再根据已重载的运算符(*,=)进行运算
*this=*this*HugeInt(faciend);
return *this;
}
//[3]-----------------------乘等于(巨型与巨型)----------------------------------//
HugeInt& HugeInt::operator *=(HugeInt& faciend)
{ //先进行类型转换 再根据已重载的运算符(*,=)进行运算
*this=*this*faciend;
return *this;
}

//----------------------------------------[*]---------------------------------------//

//[1]-----------------------乘法(字符型与巨型)----------------------------------//
HugeInt operator *(char* faciend,HugeInt& multiplicator)
{ //先进行类型转换 再根据已重载的运算符(*)进行运算
return HugeInt(faciend)*multiplicator;
}
//[2]-----------------------乘法(巨型与字符型)----------------------------------//
HugeInt operator *(HugeInt& faciend,char* multiplicator)
{ //先进行类型转换 再根据已重载的运算符(*)进行运算
return faciend*HugeInt(multiplicator);
}

//[3]-----------------------乘法(长整型与巨型)----------------------------------//
HugeInt operator *(const long int& faciend,HugeInt& multiplicator)
{ //先进行类型转换 再根据已重载的运算符(*)进行运算
return HugeInt(faciend)*multiplicator;
}
//[4]-----------------------乘法(巨型与长整型)----------------------------------//
HugeInt operator *(HugeInt& faciend,const long int& multiplicator)
{ //先进行类型转换 再根据已重载的运算符(*)进行运算
return faciend*HugeInt(multiplicator);
}
//[5]-----------------------乘法(巨型与巨型)----------------------------------//
/*重载运算符:*
参数:类对象引用(faciend 被乘数,multiplicator 乘数)
返回值:类对象
备注(主思想):总是让结点数多的数当任被乘数 循环让乘数的每一结点与被乘数的所有结点相乘
*/
HugeInt operator *(HugeInt& faciend,HugeInt& multiplicator)
{
HugeInt product;//两数相乘的积

node* curmul=new node;//新建一结点指向乘数的尾结点
curmul=multiplicator.GetEndNode();

if(faciend.GetN()>=multiplicator.GetN())//如果被乘数的位数大于等于乘数
{

short int count=0;//表示当前结点前已经与被乘数相乘过的结点数
while(curmul!=multiplicator.GetHeadNode())//从乘数尾结点开始向左扫描
{
short int carry=0;//标识进位
HugeInt temp;//建立一临时对象 存放临时的积(一个乘数结点与被乘数相乘后的积)

for(int i=0;i<count;i++)
{temp.Insert(0);}

node* curfac=new node;//新建一结点指向被乘数的尾结点
curfac=faciend.GetEndNode();

while(curfac!=faciend.GetHeadNode())//从被乘数尾结点开始向左扫描
{
temp.Insert((curmul->data*curfac->data+carry)%10000);//得到结点值

carry=(curmul->data*curfac->data+carry)/10000;//得到进位

curfac=curfac->left;//被减数结点左移
}//while循环结束
if(carry!=0)//如果还有进位
{temp.Insert(carry);}

product+=temp;//赋给最终积对象


count++;//表示执行完一个乘数结点与被乘数所有结点的相乘运算

curmul=curmul->left;//乘数结点左移

}//while循环结束

if((faciend.GetHeadNode()->data+multiplicator.GetHeadNode()->data)==1) //如果两数异号
return -product;
else//如果两数同号

return product;

}//如果被乘数的位数大于乘数情况结束

else//如果被乘数的位数小于乘数 则反过来乘
{
return multiplicator*faciend;

}
}



//-------------------------------------[%]---------------------------------------------//

//[1]------------------------%(求余 巨型与字符型)------------------------------//
HugeInt operator %(HugeInt dividend,char* divisor)
{ //先进行类型转换 再根据已重载的运算符(%)进行运算
return dividend%HugeInt(divisor);
}
//[2]------------------------%(求余 字符型与巨型)------------------------------//
HugeInt operator %(char* dividend,HugeInt divisor)
{ //先进行类型转换 再根据已重载的运算符(%)进行运算
return HugeInt(dividend)%divisor;
}
//[3]------------------------%(求余 巨型与长整型)------------------------------//
HugeInt operator %(HugeInt dividend,const long int divisor)
{ //先进行类型转换 再根据已重载的运算符(%)进行运算
return dividend%HugeInt(divisor);
}
//[4]------------------------%(求余 长整型与巨型)------------------------------//
HugeInt operator %(const long int dividend,HugeInt divisor)
{ //先进行类型转换 再根据已重载的运算符(%)进行运算
return HugeInt(dividend)%divisor;
}
//[5]------------------------%(求余 巨型与巨型)------------------------------//
/*重载运算符:%
参数:类对象(dividend 被除数, divisor 除数)
返回值:类对象
*/
HugeInt operator %(HugeInt dividend,HugeInt divisor)
{
if(divisor!="0")//如果除数不为零

{
HugeInt newdividend=abs(dividend);//被除数的绝对值
HugeInt newdivisor=abs(divisor);//除数的绝对值
HugeInt quo;//商
HugeInt residual;//余数
if(newdividend>newdivisor)//被除数的绝对值大于除数的绝对值
{ //short int mulcount=0;
quo=newdividend/newdivisor;//进行"/"运算
residual=newdividend-newdivisor*quo;//求余

}
else//被除数的绝对值小于除数的绝对值
{ residual=newdividend;//余数为被除数
}

//根据被除数符号返回相应值(余数符号跟被除数符号相同 与除数符号无关)
if(dividend.GetHeadNode()->data==0)
{
return residual;
}
else
{
return -residual;
}


}//除数不为零的情况结束

else//除数为零的情况
{ cout<<"[输入错误]除数不能为零/n";
return HugeInt("0");
}

}
//-----------------------------------[%=]---------------------------------------//

//[1]------------------------%=(求余等于)------------------------------//
HugeInt& HugeInt::operator %=(char* div)
{
//根据已重载的运算符(%,=)进行运算
*this=*this%HugeInt(div);
return *this;
}
//[2]------------------------%=(求余等于)------------------------------//
HugeInt& HugeInt::operator %=(HugeInt& div)
{
//根据已重载的运算符(%,=)进行运算
*this=*this%div;
return *this;
}
//[3]------------------------%=(求余等于)------------------------------//
HugeInt& HugeInt::operator %=(const long int& div)
{ //先进行类型转换 再根据已重载的运算符(%,=)进行运算
*this=*this%HugeInt(div);
return *this;
}
//---------------------------------[/=]------------------------------------------------//

//[1]------------------------/=(除等于 巨型与巨型)------------------------------//
HugeInt& HugeInt::operator /=(HugeInt& dividend)
{ // 根据已重载的运算符(/,=)进行运算
*this=*this/dividend;
return *this;
}
//[2]------------------------/=(除等于 巨型与长整型)------------------------------//
HugeInt& HugeInt::operator /=(const long int& dividend)
{ //先进行类型转换 再根据已重载的运算符(/,=)进行运算
*this=*this/HugeInt(dividend);
return *this;
}
//[3]------------------------/=(除等于 巨型与字符型)------------------------------//
HugeInt& HugeInt::operator /=(char* dividend)
{ //先进行类型转换 再根据已重载的运算符(/,=)进行运算
*this=*this/HugeInt(dividend);
return *this;
}

//----------------------------------------------[/]-----------------------------------//

//[1]-----------------/(除法 字符型与巨型)---------------//
HugeInt operator /(char* dividend,HugeInt divisor)
{ //先进行类型转换 再根据已重载的运算符(/)进行运算
return HugeInt(dividend)/divisor;
}
//[2]-----------------/(除法 巨型与字符型)--------------//
HugeInt operator /(HugeInt dividend,char* divisor)
{ //先进行类型转换 再根据已重载的运算符(/)进行运算
return dividend/HugeInt(divisor);
}
//[3]------------------------/(除法 长整型与巨型)-----------//
HugeInt operator /(const long int dividend,HugeInt divisor)
{ //先进行类型转换 再根据已重载的运算符(/)进行运算
return HugeInt(dividend)/divisor;
}
//[4]-------------------------/(除法 巨型与长整型)----------//
HugeInt operator /(HugeInt dividend,const long int divisor)
{ //先进行类型转换 再根据已重载的运算符(/)进行运算
return dividend/HugeInt(divisor);
}
//[5]-------------------------/(除法 巨型与巨型)------------//
/*重载运算符:/
参数:类对象(dividend 被除数, divisor 除数)
返回值:类对象
备注:
(算法举例)
比如要算9999/20吧,因为9999>20,先将20扩大10倍(扩大2次后为2000 再扩大就比9999大了),
然后9999-2000相减(减4次 因为再减下去就是负数了)得到结果1999,
现在先把得到的第一位商存起来(第一位商就是4扩大10倍 两次 也就是400);
接着因为1999比20大,再将20扩大10倍(扩大1次得到200),
做1999-200,(减8次 )结果为399,得到第二位商80(8扩大10倍 1次),
现在399比20大,继续扩大除数(这个扩大1次 为200),做399-200(做1次),
结果为199,得到第三位商10(1扩大10倍1次),现在199比20大,但20不用在扩大了,
再扩大10倍的话就比199大了,做199-20(减9次 减后为19),因为这次除数没有扩大,
所以得到的第四位商就是9(9无需再扩大10倍多少次),现在减后的结果是19,19〈20,
就不要再算了,将得到的四次商加起来400+80+10+9=499,就是9999/20的商了
*/
HugeInt operator /(HugeInt dividend,HugeInt divisor)
{
if(divisor!="0")//如果除数不为零

{ //先转化为绝对值进行运算
HugeInt newdividend=abs(dividend);
HugeInt newdivisor=abs(divisor);
HugeInt quotient;//商

if(newdividend<newdivisor)//被除数小于除数 返回0
{ return quotient;
}
while(newdividend>=newdivisor)//被除数大于等于除数
{
HugeInt tempquo;//存放每次上商的值
short int mulcount=0;//标识除数扩大的次数(10倍10倍地扩大)
HugeInt temp=newdivisor;//建立临时对象 值为当前的除数

//先扩大除数
//当当前的除数小于被除数并且扩大10被后还是小于被除数 则继续扩大除数
while((temp<newdividend)&&((temp*10)<newdividend))
{ temp*=10;
mulcount++;//每扩大一次 次数加一
}

//经过上述扩大,执行被除数与除数(扩大后的除数)减操作 直到被除数为零或小于除数
while(newdividend!="0"&&(newdividend)>=temp)
{ newdividend-=temp;
tempquo++;//每减一次 上商的值加一
}

//根据除数扩大的次数 将上商的值扩大相同次数
while(mulcount!=0)
{ tempquo*=10;
mulcount--;
}

quotient+=tempquo;//将上商的值赋给最终的商
}//循环结束

//下面再根据符号判断返回值
if(dividend.GetHeadNode()->data+divisor.GetHeadNode()->data!=1)
{
return quotient;
}
else
{
return -quotient;
}


}//除数不为零的情况结束

else//除数为零的情况
{
cout<<"[输入错误]除数不能为零/n";
return HugeInt("0");
}



}
//*----------------------------各重载函数的实现[end]------------------------------*//

//-------------------------------主函数(测试函数)------------------------------------------//

//说明:若在编译时提示测试函数错误,前检查您的程序是否按要求重载了所需的运算符
//没有重载的话请注释掉部分测试程序

void main()
{


//---------人工检测部分-----//

//------------检测是否有对输入的字符串进行验证-------------//
cout<<"//-----------------[检测任务1]检测是否有对输入的字符串进行验证--------------///n";
cout<<"[测试用例]使用字符串-a5553,a,1a, ,+a创建对象/n";
HugeInt test1("-a5553");
HugeInt test2("a");
HugeInt test3("1a");
HugeInt test4("");
HugeInt test5("+a");
cout<<"[正确值]应该设置出错提示或有容错功能以便程序能继续运行"<<endl;
//------------检测是否定义所要求的构造函数----------------//
cout<<"/n//-----------------[检测任务2]检测是否定义所要求的构造函数-----------------///n";
HugeInt test6("+0");
HugeInt test7("-0");
HugeInt test8(-220580243);
HugeInt test9("123456789123456789123456789123456789123456789");
HugeInt test10("012");
HugeInt test11("-0012000300800");
HugeInt test12("0000000012");
cout<<"输出值如下/n"<<test6<<" "<<test7<<" "<<test8<<" "<<test9<<" "<<test10<<" "<<test11<<" "<<test12<<endl;
cout<<"[正确值]如下/n"<<"0 0 -220580243 123456789123456789123456789123456789123456789 12 -12000300800 12/n";
//---------------检测逻辑运算符是否正确重载--------------//
cout<<"/n//-----------------[检测任务3]检测逻辑运算符是否正确重载-----------------///n";
cout<<"执行0>0输出"<<(test6>test7)<<"[正确值0]/n";
cout<<"执行0==0输出"<<(test6==test7)<<"[正确值1]/n";
cout<<"执行0>-220580243输出"<<(test6>test8)<<"[正确值1]/n";
cout<<"执行-220580243<-0012000300800输出"<<(test8<test11)<<"[正确值0]/n";
cout<<"执行123456789123456789123456789123456789123456789<012输出"<<(test9<test10)<<"[正确值0]/n";
cout<<"执行0!=0输出"<<(test6!=test7)<<"[正确值0]/n";
cout<<"执行0>=0输出"<<(test6>=test7)<<"[正确值1]/n";
cout<<"执行012==0000000012输出"<<(test10==test12)<<"[正确值1]/n";
cout<<"执行0000000012<012输出"<<(test12<test10)<<"[正确值0]/n";

//---------机器检测--------//

//---------------检测对象间能否正确赋值--------------//
cout<<"/n//-----------------[检测任务4]检测对象间能否正确赋值-----------------///n";
HugeInt test13("9876543210123456789");
HugeInt test14;
test14=test13;
HugeInt test15(test14);
if((test13==test14)&&(test14==test15))
{cout<<"通过检测任务4/n";}
else
{ cout<<"未通过检测任务4/n";
}
//----------------检测(+,-*,/,%)是否正确重载---------------------------------//
cout<<"/n//-----------------[检测任务5]检测(+,-*,/,%)是否正确重载------------------///n";
cout<<"[测试用例] 表达式y=a+b*c-d/e/n";
HugeInt a(-419);
HugeInt b("10002000300040005000");
HugeInt c("-999999990001");
HugeInt d("9876543210");
HugeInt e("-110120119");
HugeInt y=(a+b*c-d/e);
cout<<"初始化:/n";
cout<<"a=-419/nb=10002000300040005000/nc=-999999990001/nd=9876543210/ne=-110120119";
cout<<"/n进入测试/n";
bool flag=false;
if(a!=(y-b*c+d/e))
{ cout<<"[发现错误]在执行表达式a==(y-b*c+d/e)时/n";
flag=true;
}
else
{cout<<"执行表达式a==(y-b*c+d/e)通过/n";
}
if((b*c)!=(y-a+d/e))
{ flag=true;
cout<<"[发现错误]在执行表达式(b*c)==(y-a+d/e)时/n";
}
else
{cout<<"执行表达式(b*c)!=(y-a+d/e)通过/n";
}
if((c*b-d/e)!=(y-a))
{ flag=true;
cout<<"[发现错误]在执行表达式(c*b-d/e)!=(y-a)时/n";
}
else
{cout<<"执行表达式(c*b-d/e)!=(y-a)通过/n";
}
if((d-d%e)!=(a+b*c-y)*e)
{ flag=true;
cout<<"[发现错误]在执行表达式(d-d%e)!=(a+b*c-y)*e时/n";
}
else
{cout<<"执行表达式(d-d%e)!=(a+b*c-y)*e通过/n";
}
if((a+b*c-y)!=(d/e))
{ flag=true;
cout<<"[发现错误]在执行表达式(y-a-b*c)!=d/e时/n";
}
else
{cout<<"执行表达式(a+b*c-y)!=(d/e)通过/n";
}
if(!flag)
{cout<<"通过检测任务5/n";}
else
{cout<<"未通过检测任务5/n";
}
//----------------检测(+=,-=,*=,/=,%=)是否正确重载---------------------------------//
//若计算表达式y=y+a+b*c-d/e后y值
//与计算表达式(d%=e;c/=d;b*=c;a-=b;y+=a;)后y值相同则通过测试//
cout<<"/n//--------------[检测任务6]检测(+=,-=,*=,/=,%=)是否正确重载----------------///n";
cout<<"[测试用例] 表达式y=y+a+b*c-d/e/n";
HugeInt source(y+(a-b*(c/(d%e))));
d%=e;
c/=d;
b*=c;
a-=b;
y+=a;
if(y==source)
{cout<<"通过检测任务6/n";
}
else
{cout<<"未通过检测任务6/n";
}

//----------------检测(++,--)是否正确重载---------------------------------//
cout<<"/n//-----------------[检测任务7]检测(++,--)是否正确重载------------------///n";
HugeInt f("1000000000000");
HugeInt g("999999999999");
if((f--)==(++g)&&(--g)==(--(++f)))
{cout<<"通过检测任务7/n";}
else
{cout<<"未通过检测任务7/n";
}

//----------------检测巨型跟整型是否正确运算---------------------------------//
cout<<"/n//-----------------[检测任务8]检测巨型跟整型是否正确运算------------------///n";

int i=rand();//产生随机数
HugeInt mynum("220580243");
bool isok=true;
if(mynum!=mynum+i-i)
{ isok=false;
}
if(mynum!=mynum*i/i+mynum*i%i)
{ isok=false;
}
if(isok)
{cout<<"通过检测任务8/n";
}
else
{cout<<"未通过检测任务8/n";
}

//----------------检测50位以上巨型相乘运算---------------------------------//
cout<<"/n//-----------------[检测任务9]检测50位以上巨型相乘运算------------------///n";
HugeInt num("220580243220580243220580243220580243220580243220580243220580243");
if(num==num*1)
{cout<<"通过检测任务9/n";
}
else
{cout<<"未通过检测任务9/n";
}

}

原创粉丝点击