大数加法 可为负数

基础题

#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <functional>
#include <iomanip>
#include <algorithm>
#include <limits>
//#include <ext/hash_map>
//using namespace __gnu_cxx;
typedef long long LL;
typedef unsigned long long ULL;
#define RDI(x) scanf("%d",&x)
#define RDI_2(x,y) scanf("%d%d",&x,&y)
#define RDD(x) scanf("%lf",&x)
#define RDD_2(x,y) scanf("%lf%lf",&x,&y)
#define RDL(x) scanf("%lld",&x)
#define RDL_2(x,y) scanf("%lld%lld",&x,&y)
#define RDS(x) scanf("%s",x)
#define RDS_2(x,y) scanf("%s%s",x,y)
#define PUTI(x) printf("%d",x)
#define PUTL(x) printf("%lld",x)
#define PUTF(x) printf("%f",x)
#define PUTC(x) putchar(x)
#define LINE putchar('\n')
#define SPACE putchar(' ')
#define REP(i,x) for(int i=0;i<int(x);++i)
#define REP_1(i,x) for(int i=1;i<=int(x);++i)
#define REP_C(i,x) for(i=0;i<int(x);++i)
#define REP_E(i,x,y) for(int i=0;i<int(x);++i,y)
#define REP_1_E(i,x,y) for(int i=1;i<=int(x);++i,y)
#define REP_1_C(i,x) for(i=1;i<=int(x);++i)
#define FOR_EDGE(i,x) for(int i=head[x];~i;i=edge[i].next)
#define FOR_EDGE2(x,i,y) for(int i=head[x][y];~i;i=edge[i].next)
#define FOR(i,a,b) for(int i=int(a);i<=int(b);++i)
#define FORD(i,a,b) for(int i=int(a);i>=int(b);--i)
#define DWN(i,x) for(int i=int(x-1);i>=0;--i)
#define DWN_1(i,x) for(int i=int(x);i>0;--i)
#define FIL(x,v) memset(x,v,sizeof(x))
#define CLR(x) memset(x,0,sizeof(x))
#define ALL(x) x.begin(),x.end()
#define p_queue priority_queue
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define fst first
#define snd second
#define x first
#define y second
#define mp(x,y) make_pair(x,y)
//#define check(x) printf("%s=%d\n",#x,x)
using namespace std;
template<typename T>
T gcd(T a, T b){ return b == 0 ? a : gcd(b, a%b); }
template<typename T>
T lcm(T a, T b){ return a / gcd(a, b)*b; }
template<typename T>
T ext_gcd(T a, T b, T& x, T& y)
{
    if (b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    int d = ext_gcd(b, a%b, y, x);
    y -= x*(a / b);
    return d;
}
template<typename T>
T quick_pow(T a, T b)
{
    if (b == 0) return 1;
    T p = quick_pow(a, b >> 1);
    p = p*p;
    if (b & 1) p =p*a;
    return p;
}
double combination(int n, int r)
{
    if (r<n - r) return combination(n, n - r);
    double s = 1.0;
    REP_1(i, n - r) s *= (r + i), s /= i;
    return s;
}
template<typename T>
inline void read(T& v)
{
    T ret = 0, sgnv = 1;
    char p;
    while (!isdigit(p = getchar())) if (p == '-') sgnv = -1;
    do{
        ret = (ret << 3) + (ret << 1) + p - '0';
    } while (isdigit(p = getchar()));
    v = sgnv*ret;
}
const double eps=1e-8;
inline int sgn(double x){ return (x>-eps)-(x<eps); }
const int mod=1000000007;
//const int INF = numeric_limits<int>::max();
const int INF = 0x7f7f7f7f;
//const int INFCELL = 0x7f;
#define MAX 10000+5
#define lucknum 19960308
#define ONLINE_JUDGE
class BigNum
{
public:
    static const int MAXN = 10000;  
    static const int DLEN = 4;    //每一位存4个数字
public:
    BigNum() : sign(1), len(1) { CLR(a); }
    BigNum(const char *);
    BigNum& operator+=(const BigNum &);  
    bool compare(const BigNum &) const;   //比较两个数的绝对值大小
    friend ostream& operator<<(ostream &, const BigNum &);
private:
    int a[MAX];   //记录数字
    int len;    //记录a数组的长度
    int sign;   //记录数的正负
};

ostream& operator<<(ostream &out, const BigNum &T)
{
    if(T.sign < 0)
        out << "-";
    out << T.a[T.len-1];
    for(int i = T.len - 2; i >= 0; --i)
        out << setw(4) << setfill('0') << T.a[i];
    return out;
}

BigNum::BigNum(const char *s)
{
    int L, k, t, ed = 0, index = 0;
    sign = 1;
    L = strlen(s);
    len = L / DLEN;
    if(L % DLEN)    len++;
    if(s[0] == '-')
    {
        ed = 1;
        sign = -1;
        if(L % DLEN == 1)
            len--;
    }
    for(int i = L - 1; i >= ed; i -= DLEN)
    {
        t = 0;
        k = i - DLEN + 1;
        if(k < ed)  k = ed;
        for(int j = k; j <= i; ++j)
            t = t * 10 + s[j] - '0';
        a[index++] = t;
    }
}

BigNum& BigNum::operator+=(const BigNum &rhs)
{
    if(sign * rhs.sign > 0)   //同号
    {
        len = max(len, rhs.len);
        for(int i = 0, g = 0; g || i < len; ++i)
        {
            a[i] += g + rhs.a[i];
            g = a[i] / MAXN;
            a[i] %= MAXN;
        }
        if(a[len] != 0) len++;
    }
    else
    {
        BigNum t(rhs);
        if(!compare(rhs))
        {
            t = *this;
            *this = rhs;
        }
        for(int i = 0; i < len; ++i)
        {
            if(a[i] >= t.a[i])
                a[i] -= t.a[i];
            else
            {
                int j = i + 1;
                while(a[j] == 0)    j++;
                a[j--]--;
                while(j > i)    a[j--] += MAXN - 1;
                a[i] += MAXN - t.a[i];
            }
        }
        while(a[len - 1] == 0 && len > 0)   len--;
        if(len == 0)    
        {
            len = 1;
            sign = 1;
        }
    }
    return *this;
}
bool BigNum::compare(const BigNum &rhs) const
{
    if(len > rhs.len)   return true;
    if(len < rhs.len)   return false;
    for(int i = len - 1; i >=0 ; --i)
    {
        if(a[i] > rhs.a[i]) return true;
        if(a[i] < rhs.a[i]) return false;
    }
    return false;
}

BigNum operator+(const BigNum &lhs, const BigNum &rhs)
{
    BigNum sum(lhs);    //调用默认拷贝构造函数
    sum += rhs;
    return sum;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.in","r",stdin);
#endif
    char s1[MAX], s2[MAX];
    RDS_2(s1, s2);
    BigNum a(s1), b(s2);
    cout << a + b;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值