orz CYX
針對帶負數的高精度數運算,可以採用補碼錶示法。
補碼錶示法即用原碼錶示正數,補碼錶示負數。
補碼錶示法表示的任何數之間都可以進行加法運算,捨棄了減法,簡化了代碼。
對於乘法運算,先將補碼錶示的負數轉化爲正數,運算之後得到若爲正數,再轉化爲負數。
//補碼高精度算法。
#include
#include
#include
#define R register
#define ll long long
#define base 1000000000
#define dmax(_a,_b)(_a)>(_b)?(_a):(_b)
using namespace std;
struct BigNum
{
int num[10010],len;
void clear()
{
memset(num,0,sizeof(num));
len=1;
}
inline void flip()
{
R int i;
for(i=1;i<=len&&!num[i];++i);
if(i>len)return;
num[i]=base-num[i];
for(++i;i<=len;++i)num[i]=base-1-num[i];
num[len]-=base;
}
void scan(const char *ss)
{
R int i,j,k,rev=0,cnt=1;
while(ss[0]<'0'||ss[0]>'9'){if(ss[0]=='-')rev=1;++ss;}
memset(num,0,sizeof(num));
for(i=0;ss[i]>='0'&&ss[i]<='9';++i);
for(j=i-1,k=1;j>=0;--j)
{
num[k]+=cnt*(ss[j]-'0');
cnt=(cnt<<3)+(cnt<<1);
if(cnt==base)cnt=1,++k;
}
if(!num[k])--k;
len=k;
if(rev)flip();
}
void print()
{
R int rev=0,i;
if(num[len]<0)rev=1,flip(),printf("-");
while(len>1&&!num[len])--len;
printf("%d",num[len]);
for(i=len-1;i>=1;--i)
printf("%09d",num[i]);
if(rev)flip();
}
inline BigNum operator + (const BigNum &b1)const
{
R BigNum ret;
ret.clear();
R int i,flow=0;
ret.len=dmax(b1.len,len);
for(i=1;i<=ret.len;++i)
{
ret.num[i]=num[i]+b1.num[i]+flow;
flow=ret.num[i]/base,ret.num[i]%=base;
while((flow>0||i1&&!num[len])--len;
if(b1.num[b1.len]<0)b1.flip(),rev2=1;
while(b1.len>1&&!b1.num[b1.len])--b1.len;
ret.len=len+b1.len;
for(i=1;i<=len;++i)
for(j=1;j<=b1.len;++j)
{
tmp=ret.num[i+j-1]+(ll)num[i]*b1.num[j];
ret.num[i+j-1]=tmp%base,ret.num[i+j]+=tmp/base;
}
while(ret.len>1&&!ret.num[ret.len])--ret.len;
if(rev1)flip();
if(rev2)b1.flip();
if(rev1^rev2)ret.flip();
return ret;
}
};
char q1[10010],s[10010];
struct BigNum q2[2010];
int n;
int main()
{
R int i,j,k,des;
R int t1=0,t2=0;
R BigNum sum;
scanf("%s",s+1);
n=strlen(s+1);
s[0]='(',s[n+1]=')',s[n+2]='\0',++n;
for(i=0;i<=n;)
{
des=-1;
if((s[i]=='+'||s[i]=='-'||s[i]==')')&&q1[t1]=='*'&&s[i-1]!='*')
{
sum.clear(),sum.num[1]=1;
while(q1[t1]=='*')sum=sum*q2[t2],--t1,--t2;
sum=sum*q2[t2],q2[t2]=sum;
}
if(s[i]==')')
{
sum.clear();
while(q1[t1]!='(')
{
if(q1[t1]=='+')sum=sum+q2[t2];
else q2[t2].flip(),sum=sum+q2[t2];
--t1,--t2;
}
--t1,q2[t2]=sum+q2[t2];
}
if( ((s[i]=='-'||s[i]=='+')&&( (s[i+1]>='0'&&s[i+1]<='9' ) || s[i+1]=='-' ||s[i+1]=='+' )) || (s[i]>='0'&&s[i]<='9') )
{
if(s[i-1]!='*'&&s[i-1]!='(')q1[++t1]='+';
q2[++t2].scan(s+i);
des=i;
while(s[des]<'0'||s[i]>'9')++des;
while(s[des]>='0'&&s[des]<='9')++des;
}else{
if(s[i]!=')')q1[++t1]=s[i];
des=i+1;
}
if(des!=-1)i=des;
}
q2[t2].print();
return 0;
}