/ 好叫你见识见识,什么叫做又臭又长的裹脚布代码,这篇帖子也是 /
题目
(大数运算)
long long类型一般占8个字节是C/C++中的精度最高的整数类型,取值范围在 -9223372036854775808~+9223372036854775807。在很多场景中,整数范围超出了long long的最值,例如在非对称加密中密钥长度一般为1024bit,转换为十进制数将超过300位,因此不能直接用内置的整数类型来运算。请编写大数运算类型MyBigInteger,使其支持大数据的加法,减法,乘法的运算。
(除法为选做功能,除法运算符合C/C++中的整数除法运算的规则,有20%的测试用例包含除法运算)
【输入】
大整数n,n的位数<=200
大整数m,m的位数<=200
运算符(+,-,*, /)
【输出】n和m的运算结果
例如:
【输入】
56891237265
32156789215
-
【输出】
24734448050
思路
非常懒惰没有去写BigInt的类,直接用的自定义的双向链表,解题分为五部:写双向链表类,输入,判断,计算,输出。
定义类
基本都是书上那一套,没啥好说的,多加了一个倒序遍历,头插和尾插,用起来会顺手些。
enum Error_code{underflow,overflow,success,Range_error};
typedef int Target;
struct Node
{
Target entry;
Node* next;
Node* back;
Node();
Node(Target item,Node *link_back=NULL,Node *link_next=NULL);
};
Node::Node()
{
next=NULL;
back=NULL;
}
Node::Node(Target item,Node *link_back,Node *link_next)
{
entry=item;
next=link_next;
back=link_back;
}
class List
{
public:
List();
~List();
List(const List ©);
void operator= (const List ©);
int size( ) const;
bool is_full( ) const;
bool is_empty( ) const;
void clear( );
void traverse(void (*visit)(Target &));
void antitraverse(void (*visit)(Target &));
Error_code retrieve(int position, Target &x) const;
Error_code replace(int position, const Target &x);
Error_code remove(int position, Target &x);
Error_code insert(int position, const Target &x);
Error_code back_insert(const Target &x);
Error_code front_insert(const Target &x);
protected:
int count;
mutable int current_position;
mutable Node *current;
void set_position(int position) const;
};
List::List()
{
count = 0;
current_position = -1;
current = NULL;
}
List::List(const List ©)
{
count=copy.count;
current_position=copy.current_position;
Node *new_node,*old_node=copy.current;
if(old_node==NULL)
current=NULL;
else
{
new_node=current=new Node(old_node->entry);
while(old_node->next!=NULL)
{
old_node=old_node->next;
new_node->next=new Node(old_node->entry,new_node);
new_node=new_node->next;
}
old_node=copy.current;
new_node=current;
while(old_node->back!=NULL)
{
old_node=old_node->back;
new_node->back=new Node(old_node->entry,NULL,new_node);
new_node=new_node->back;
}
}
}
void List::operator= (const List ©)
{
List new_copy(copy);
clear();
count=new_copy.count;
current_position=new_copy.current_position;
current=new_copy.current;
new_copy.current=NULL;
new_copy.current_position=0;
new_copy.count=0;
}
List::~List()
{
clear();
}
void List::clear()
{
Node *p,*q;
if(current==NULL)
return;
for(p=current->back;p;p=q)
{
q=p->back;
delete p;
}
for(p=current;p;p=q)
{
q=p->next;
delete p;
}
count=0;
current=NULL;
current_position=-1;
}
int List::size() const
{
return count;
}
bool List::is_empty() const
{
return count==0;
}
bool List::is_full() const
{
Node *new_node;
new_node=new Node;
if(new_node==NULL)
return true;
else
{
delete new_node;
return false;
}
}
void List::set_position(int position) const
{
if (position>=current_position)
for ( ; current_position != position; current_position++)
current=current->next;
else
for ( ; current_position != position; current_position--)
current=current->back;
}
void List::traverse(void (*visit)(Target &))
{
Node *q=current;
if(q!=NULL)
for(;q->back;q=q->back) ;
for(;q;q=q->next)
(*visit)(q->entry);
}
void List::antitraverse(void (*visit)(Target &))
{
Node *p=current;
if(p!=NULL)
for(;p->next;p=p->next);
for(;p;p=p->back)
(*visit)(p->entry);
}
Error_code List::replace(int position,const Target &x)
{
if (position < 0 || position > count)
return Range_error;
set_position(position);
current->entry=x;
return success;
}
Error_code List::insert(int position, const Target &x)
{
if (position < 0 || position > count)
return Range_error;
Node *new_node, *preceding, *following;
if (position==0)
{
if(count==0)
following=NULL;
else
{
set_position(0);
following=current;
}
preceding=NULL;
}
else
{
set_position(position-1);
preceding=current;
following=preceding->next;
}
new_node=new Node(x,preceding,following);
if(new_node==NULL) return overflow;
if(preceding!=NULL)
preceding->next=new_node;
if(following!=NULL)
following->back=new_node;
current=new_node;
current_position=position;
count++;
return success;
}
Error_code List::remove(int position,Target &x)
{
if (position<0||position>=count)
return Range_error;
Node *old_node, *neighbor;
set_position(position);
old_node=current;
if (neighbor=current->back)
{
neighbor->next=current->next;
}
if (neighbor=current->next)
{
neighbor->back=current->back;
current=neighbor;
}
else
{
current=current->back;
current_position--;
}
x=old_node->entry;
delete old_node;
count--;
return success;
}
Error_code List::back_insert(const Target &x)
{
insert(count,x);
return success;
}
Error_code List::front_insert(const Target &x)
{
insert(0,x);
return success;
}
Error_code List::retrieve(int position, Target &x) const
{
if (position < 0 || position >= count)
return Range_error;
set_position(position);
x=current->entry;
return success;
}
void print(Target &x)
{
cout << x ;
}
输入
大数作为字符串被读入,然后逐位放进 list 中,考虑到进位,我们将其倒序存放(头插),同时定义一个符号位sym,后面用得上。
void input(List &info,int &sym)
{
string s;
cin >> s;
if(s[0]=='-')
{
sym=-1;
for(int i=1;i<s.size();i++)
{
info.front_insert(s[i]-'0');
}
}
else
{
sym=0;
for(int i=0;i<s.size();i++)
{
info.front_insert(s[i]-'0');
}
}
}
判断
在进行减法和除法运算的时候,我需要判断两个数的大小关系,有时还需要将他们交换。
比较大小时先比较位数长短关系,位数相同时就从高位开始比较,直到出现不同。
非交换的判断函数和判断交换函数只有最后几行不同。
void judge_and_swap(List &p,List &a,int &flag)
{
flag=0;
int lenp=p.size(),lena=a.size();
if(lenp>lena)
flag=1;
else if(lenp<lena)
flag=-1;
else
{
int cnt=lenp-1;
while(cnt>=0)
{
Target np,na;
p.retrieve(cnt,np);
a.retrieve(cnt,na);
if(np>na)
{
flag=1;
break;
}
else if(na>np)
{
flag=-1;
break;
}
cnt--;
}
}
if(flag==-1)
{
List temp;
temp=p;
p=a;
a=temp;
}
}
计算
加法
纯模拟,从低位开始两两相加,只留个位,十位作为进位参与到下次计算,两个list的所有结点都参与过运算之后进位如果大于0,则再进位。
感觉这里对于两个加数不同长度的处理还是蛮妙的。
List bigintadd (List pre,List aft)
{
List res;
Target pret,aftt;
int carry=0,cntp=0,cnta=0;
while(cntp<pre.size()||cnta<aft.size())
{
int sum=carry;
if(cntp<pre.size())
{
pre.retrieve(cntp,pret);
sum+=pret;
cntp++;
}
if(cnta<aft.size())
{
aft.retrieve(cnta,aftt);
sum+=aftt;
cnta++;
}
carry=sum/10;
res.back_insert(sum%10);
}
if(carry>0)
res.back_insert(carry);
return res;
}
减法
减法比加法啰嗦一步,为了保证 bigintsub 函数执行完之后结果 list 中每一位都大于零,我们调用比较交换函数,确保大数减小数。
之后还是模拟,被减数的位减去减数的位,如果结果小于零就加十,然后进位设置为-1参与下次运算。接着根据比较函数得到的两数大小给数据加符号,最后再剔除一手高位退位产生的前导0。
List bigintsub (List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
if(flag1==0)
res.back_insert(0);
else
{
int carry=0,cntp=0,cnta=0;
while(cntp<pre.size()||cnta<aft.size())
{
int sum=carry;
if(cntp<pre.size())
{
pre.retrieve(cntp,pret);
sum+=pret;
cntp++;
}
if(cnta<aft.size())
{
aft.retrieve(cnta,aftt);
sum-=aftt;
cnta++;
}
if(sum<0)
{
sum+=10;
carry=-1;
}
else
{
carry=0;
}
res.back_insert(sum%10);
}
if(flag1==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
int rest;
res.retrieve(res.size()-1,rest);
while(rest==0&&(!res.is_empty()))
{
res.remove(res.size()-1,rest);
res.retrieve(res.size()-1,rest);
}
return res;
}
乘法
每次从乘数的低位取一个数字,和另一个乘数的每一位数字相乘,还是进位那一套,最后根据一开始取的数字的位数,在每次乘积的低位补上相应个数的0,最后把这些乘积加起来就可以了。
List bigintmult(List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
Target i2;
int cnt=0;
while(!aft.is_empty())
{
List temps,tempr;
aft.remove(0,i2);
temps=pre;
if(!temps.is_empty())
{
int sum=0,carry=0;
while(!temps.is_empty())
{
Target i1;
temps.remove(0,i1);
sum=i1*i2+carry;
carry=sum/10;
sum%=10;
tempr.back_insert(sum);
}
if(carry>0)
tempr.back_insert(carry);
}
for(int i=0;i<cnt;i++)
tempr.front_insert(0);
cnt++;
res=bigintadd(res,tempr);
}
return res;
}
除法
除法是折磨我时间最长的,一开始想到的思路是用被除数减除数,直到被减数小于减数,计算减的次数,但是这样做毫无疑问会超时,于是换了思路,本质也是做减法,但是最开始给减数补上0,0的个数为二者位数差,然后每次补零的个数递减。
举个栗子:6666 / 23 。按照一开始的思路是 6666 = 23*289+19 ,需要计算 289 次,结果为 289,改良之后为 6666=2300*2+230*8+23*9+19,只需要计算19次,结果为 200+80+9=289,完全一致嘛。
一些特殊情况就是被除数小于除数或者有0存在,就直接将结果返回为0。
List bigintdiv(List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
pre.retrieve(pre.size()-1,pret);
aft.retrieve(aft.size()-1,aftt);
if(flag1==-1||pret==0||aftt==0)
{
res.back_insert(0);
return res;
}
else
{
List temp;
int cnt=pre.size()-aft.size();
temp.back_insert(1);
res.back_insert(0);
for(int i=0;i<cnt;i++) //补零
{
temp.front_insert(0);
aft.front_insert(0);
}
while(cnt>=0)
{
int flag2;
judge(pre,aft,flag2);
while(flag2!=-1)
{
pre=bigintsub(pre,aft);
int t;
pre.retrieve(pre.size()-1,t);
while(t==0&&(!pre.is_empty()))
{
pre.remove(pre.size()-1,t);
pre.retrieve(pre.size()-1,t);
}
judge(pre,aft,flag2);
res=bigintadd(res,temp);
}
cnt--;
Target tmp;
temp.remove(0,tmp); //去零
aft.remove(0,tmp);
}
}
return res;
}
符号判断
之前的计算函数都是默认输入为两个整数,但是实际情况更加复杂,在运用时需要对具体情况,比如数据的正负,数据的长度等进行判断,比如“-” + “-” , “+” - “-”……
好叭我承认这样处理确实是因为我很愚蠢很笨蛋。
void solve(List &a,List &b,List &res,char s,int flaga,int flagb)
{
int flag=flaga+flagb;
if(s=='+'&&flag==0)
res=bigintadd(a,b);
else if(s=='+'&&flag==-2)
{
res=bigintadd(a,b);
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
else if((s=='+'&&flag==-1))
{
int cnt;
judge_and_swap(a,b,cnt);
res=bigintsub(a,b);
if((cnt==1&&flaga==-1)||(cnt==-1&&flagb==-1))
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
else if(s=='-'&&flaga==-1&&flagb==0)
{
res=bigintadd(a,b);
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
else if(s=='-'&&flaga==0&&flagb==-1)
{
res=bigintadd(a,b);
}
else if(s=='-')
res=bigintsub(a,b);
else if(s=='*')
{
res=bigintmult(a,b);
if(flag==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
else if(s=='/')
{
res=bigintdiv(a,b);
if(flag==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
int rest;
res.retrieve(res.size()-1,rest);
while(rest==0&&(!res.is_empty()))
{
res.remove(res.size()-1,rest);
res.retrieve(res.size()-1,rest);
}
if(!res.is_empty())
res.antitraverse(print);
else
cout << 0;
}
输出
具体代码写在上面的solve函数里了,就是再判断一次前导0,然后把 list 里的内容逆序输出即可。
完整代码
#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
enum Error_code{underflow,overflow,success,Range_error};
typedef int Target;
struct Node
{
Target entry;
Node* next;
Node* back;
Node();
Node(Target item,Node *link_back=NULL,Node *link_next=NULL);
};
Node::Node()
{
next=NULL;
back=NULL;
}
Node::Node(Target item,Node *link_back,Node *link_next)
{
entry=item;
next=link_next;
back=link_back;
}
class List
{
public:
List();
~List();
List(const List ©);
void operator= (const List ©);
int size( ) const;
bool is_full( ) const;
bool is_empty( ) const;
void clear( );
void traverse(void (*visit)(Target &));
void antitraverse(void (*visit)(Target &));
Error_code retrieve(int position, Target &x) const;
Error_code replace(int position, const Target &x);
Error_code remove(int position, Target &x);
Error_code insert(int position, const Target &x);
Error_code back_insert(const Target &x);
Error_code front_insert(const Target &x);
protected:
int count;
mutable int current_position;
mutable Node *current;
void set_position(int position) const;
};
List::List()
{
count = 0;
current_position = -1;
current = NULL;
}
List::List(const List ©)
{
count=copy.count;
current_position=copy.current_position;
Node *new_node,*old_node=copy.current;
if(old_node==NULL)
current=NULL;
else
{
new_node=current=new Node(old_node->entry);
while(old_node->next!=NULL)
{
old_node=old_node->next;
new_node->next=new Node(old_node->entry,new_node);
new_node=new_node->next;
}
old_node=copy.current;
new_node=current;
while(old_node->back!=NULL)
{
old_node=old_node->back;
new_node->back=new Node(old_node->entry,NULL,new_node);
new_node=new_node->back;
}
}
}
void List::operator= (const List ©)
{
List new_copy(copy);
clear();
count=new_copy.count;
current_position=new_copy.current_position;
current=new_copy.current;
new_copy.current=NULL;
new_copy.current_position=0;
new_copy.count=0;
}
List::~List()
{
clear();
}
void List::clear()
{
Node *p,*q;
if(current==NULL)
return;
for(p=current->back;p;p=q)
{
q=p->back;
delete p;
}
for(p=current;p;p=q)
{
q=p->next;
delete p;
}
count=0;
current=NULL;
current_position=-1;
}
int List::size() const
{
return count;
}
bool List::is_empty() const
{
return count==0;
}
bool List::is_full() const
{
Node *new_node;
new_node=new Node;
if(new_node==NULL)
return true;
else
{
delete new_node;
return false;
}
}
void List::set_position(int position) const
{
if (position>=current_position)
for ( ; current_position != position; current_position++)
current=current->next;
else
for ( ; current_position != position; current_position--)
current=current->back;
}
void List::traverse(void (*visit)(Target &))
{
Node *q=current;
if(q!=NULL)
for(;q->back;q=q->back) ;
for(;q;q=q->next)
(*visit)(q->entry);
}
void List::antitraverse(void (*visit)(Target &))
{
Node *p=current;
if(p!=NULL)
for(;p->next;p=p->next);
for(;p;p=p->back)
(*visit)(p->entry);
}
Error_code List::replace(int position,const Target &x)
{
if (position < 0 || position > count)
return Range_error;
set_position(position);
current->entry=x;
return success;
}
Error_code List::insert(int position, const Target &x)
{
if (position < 0 || position > count)
return Range_error;
Node *new_node, *preceding, *following;
if (position==0)
{
if(count==0)
following=NULL;
else
{
set_position(0);
following=current;
}
preceding=NULL;
}
else
{
set_position(position-1);
preceding=current;
following=preceding->next;
}
new_node=new Node(x,preceding,following);
if(new_node==NULL) return overflow;
if(preceding!=NULL)
preceding->next=new_node;
if(following!=NULL)
following->back=new_node;
current=new_node;
current_position=position;
count++;
return success;
}
Error_code List::remove(int position,Target &x)
{
if (position<0||position>=count)
return Range_error;
Node *old_node, *neighbor;
set_position(position);
old_node=current;
if (neighbor=current->back)
{
neighbor->next=current->next;
}
if (neighbor=current->next)
{
neighbor->back=current->back;
current=neighbor;
}
else
{
current=current->back;
current_position--;
}
x=old_node->entry;
delete old_node;
count--;
return success;
}
Error_code List::back_insert(const Target &x)
{
insert(count,x);
return success;
}
Error_code List::front_insert(const Target &x)
{
insert(0,x);
return success;
}
Error_code List::retrieve(int position, Target &x) const
{
if (position < 0 || position >= count)
return Range_error;
set_position(position);
x=current->entry;
return success;
}
void print(Target &x)
{
cout << x ;
}
void input(List &info,int &sym)
{
string s;
cin >> s;
if(s[0]=='-')
{
sym=-1;
for(int i=1;i<s.size();i++)
{
info.front_insert(s[i]-'0');
}
}
else
{
sym=0;
for(int i=0;i<s.size();i++)
{
info.front_insert(s[i]-'0');
}
}
}
List bigintadd (List pre,List aft)
{
List res;
Target pret,aftt;
int carry=0,cntp=0,cnta=0;
while(cntp<pre.size()||cnta<aft.size())
{
int sum=carry;
if(cntp<pre.size())
{
pre.retrieve(cntp,pret);
sum+=pret;
cntp++;
}
if(cnta<aft.size())
{
aft.retrieve(cnta,aftt);
sum+=aftt;
cnta++;
}
carry=sum/10;
res.back_insert(sum%10);
}
if(carry>0)
res.back_insert(carry);
return res;
}
void judge_and_swap(List &p,List &a,int &flag)
{
flag=0;
int lenp=p.size(),lena=a.size();
if(lenp>lena)
flag=1;
else if(lenp<lena)
flag=-1;
else
{
int cnt=lenp-1;
while(cnt>=0)
{
Target np,na;
p.retrieve(cnt,np);
a.retrieve(cnt,na);
if(np>na)
{
flag=1;
break;
}
else if(na>np)
{
flag=-1;
break;
}
cnt--;
}
}
if(flag==-1)
{
List temp;
temp=p;
p=a;
a=temp;
}
}
void judge(List p,List a,int &flag)
{
flag=0;
int lenp=p.size(),lena=a.size();
if(lenp>lena)
flag=1;
else if(lenp<lena)
flag=-1;
else
{
int cnt=lenp-1;
while(cnt>=0)
{
Target np,na;
p.retrieve(cnt,np);
a.retrieve(cnt,na);
if(np>na)
{
flag=1;
break;
}
else if(na>np)
{
flag=-1;
break;
}
cnt--;
}
}
}
List bigintsub (List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
if(flag1==0)
res.back_insert(0);
else
{
int carry=0,cntp=0,cnta=0;
while(cntp<pre.size()||cnta<aft.size())
{
int sum=carry;
if(cntp<pre.size())
{
pre.retrieve(cntp,pret);
sum+=pret;
cntp++;
}
if(cnta<aft.size())
{
aft.retrieve(cnta,aftt);
sum-=aftt;
cnta++;
}
if(sum<0)
{
sum+=10;
carry=-1;
}
else
{
carry=0;
}
res.back_insert(sum%10);
}
if(flag1==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
int rest;
res.retrieve(res.size()-1,rest);
while(rest==0&&(!res.is_empty()))
{
res.remove(res.size()-1,rest);
res.retrieve(res.size()-1,rest);
}
return res;
}
List bigintmult(List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
Target i2;
int cnt=0;
while(!aft.is_empty())
{
List temps,tempr;
aft.remove(0,i2);
temps=pre;
if(!temps.is_empty())
{
int sum=0,carry=0;
while(!temps.is_empty())
{
Target i1;
temps.remove(0,i1);
sum=i1*i2+carry;
carry=sum/10;
sum%=10;
tempr.back_insert(sum);
}
if(carry>0)
tempr.back_insert(carry);
}
for(int i=0;i<cnt;i++)
tempr.front_insert(0);
cnt++;
res=bigintadd(res,tempr);
}
return res;
}
List bigintdiv(List pre,List aft)
{
List res;
Target pret,aftt;
int flag1;
judge_and_swap(pre,aft,flag1);
pre.retrieve(pre.size()-1,pret);
aft.retrieve(aft.size()-1,aftt);
if(flag1==-1||pret==0||aftt==0)
{
res.back_insert(0);
return res;
}
else
{
List temp;
int cnt=pre.size()-aft.size();
temp.back_insert(1);
res.back_insert(0);
for(int i=0;i<cnt;i++)
{
temp.front_insert(0);
aft.front_insert(0);
}
while(cnt>=0)
{
int flag2;
judge(pre,aft,flag2);
while(flag2!=-1)
{
pre=bigintsub(pre,aft);
int t;
pre.retrieve(pre.size()-1,t);
while(t==0&&(!pre.is_empty()))
{
pre.remove(pre.size()-1,t);
pre.retrieve(pre.size()-1,t);
}
judge(pre,aft,flag2);
res=bigintadd(res,temp);
}
cnt--;
Target tmp;
temp.remove(0,tmp);
aft.remove(0,tmp);
}
}
return res;
}
void solve(List &a,List &b,List &res,char s,int flaga,int flagb)
{
int flag=flaga+flagb;
if(s=='+'&&flag==0)
res=bigintadd(a,b);
else if(s=='+'&&flag==-2)
{
res=bigintadd(a,b);
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
else if((s=='+'&&flag==-1))
{
int cnt;
judge_and_swap(a,b,cnt);
res=bigintsub(a,b);
if((cnt==1&&flaga==-1)||(cnt==-1&&flagb==-1))
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
else if(s=='-'&&flaga==-1&&flagb==0)
{
res=bigintadd(a,b);
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
else if(s=='-'&&flaga==0&&flagb==-1)
{
res=bigintadd(a,b);
}
else if(s=='-')
res=bigintsub(a,b);
else if(s=='*')
{
res=bigintmult(a,b);
if(flag==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
else if(s=='/')
{
res=bigintdiv(a,b);
if(flag==-1)
{
int rest;
res.retrieve(res.size()-1,rest);
rest*=-1;
res.replace(res.size()-1,rest);
}
}
int rest;
res.retrieve(res.size()-1,rest);
while(rest==0&&(!res.is_empty()))
{
res.remove(res.size()-1,rest);
res.retrieve(res.size()-1,rest);
}
if(!res.is_empty())
res.antitraverse(print);
else
cout << 0;
}
int main()
{
List pre,aft,final;
int flaga=0,flagb=0;
char s;
input(pre,flaga);
input(aft,flagb);
cin >> s;
solve(pre,aft,final,s,flaga,flagb);
return 0;
}
小结
减法部分的符号判断我觉得是不全面的,ac就说明,欸题目数据很弱欸。
整个代码都透出一种不灵光,笨拙的气息,封装性和鲁棒性都很差,确实是又臭又长,要学的东西还很多啊。
因为代码里面过多的使用了传引用,静态评估分基本被扣光了,OCLint真的很严格。
希望以后会来更新这篇博文,把BigInt的类补上,把符号重载写一写,再封装的好一些。
最近确实太忙了,计算机系统的实验挺费时间的,但也挺有趣的,五一找时间会写一写。
推荐
这一篇是大佬室友写的,比我的简洁多了。
https://blog.csdn.net/weixin_47003107/article/details/105848624
这一篇是同学推荐的,很吊的大数模板。
https://www.cnblogs.com/feiyue-1779930274/p/11628128.html