ACM_大数运算 模板&&讲解&&各大oj题目


///////////////////////////////////////////////////////////////////////////////////////////////////////
作者:tt2767
声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0
查看本文更新与讨论请点击:http://blog.csdn.net/tt2767/article/details/45420067
链接被删请百度: CSDN t2767
///////////////////////////////////////////////////////////////////////////////////////////////////////


本模板的代码中,大数加,减,乘,除,求幂以及阶乘已经通过各大oj,取模算法暂时没有做到大数运算的题,但本地测试正确。

如果你还不太明白大数运算,建议你拿一张白纸边看边试一下,并且本方法默认大数字符串初始化为‘\0’。

一. 大数加法的原理
想象一下我们手算加法的时候怎么算?比如说678 + 78 ,开始算的时候是第一个数的个位 + 第二个数的个位,也就是8+8=16,结果中的个位是6,而1要进位进到十位上去,我们可以设一个变量carry来代表进位的值,由于单个数相加的最大值为9+9=18 所以carry的只能是1或0 。再向下看,个位算完了应该算十位了,由于个位有进位,所以计算十位时是carry+7+7 == 1+7+7 = 15,这时十位的值为5,1要进位,carry=1;最后看百位,我们手算的时候由于78没有百位的值所以百位的值为carry+6,但是计算机对齐的时候由于初始化为‘\0’所以百位对齐的值是‘\0‘会造成计算错误,所以,在大数相加的时候应该对较小的数补充前导0使两数位对齐。如果是999+999这种情况,要考虑新增的位数,所以我们把数组转置,让低位在前,高位在后计算。

二. 大数减法
与大数加法类似,只不过,不需要对齐数位,把进位改成借位了。

三. 大数乘法
大数乘法的实现要调用大数加法,想一下手算的时候怎么算??还是算678*78,手算的时候会先算8*678=5424,然后算7*678=4746,但是4746会错开一位去写,因为这里的7其实是70所以4746真实值为47460,然后把两个结果相加得到的最后乘法运算的结果为5424+47460 = 52884
四. 大数除法
(这里说的除法是一个较大的数除以较小的数,其它的都可以转化成这种算法或直接得出结果)
大数除法是这里最耗费时间,也是最复杂的算法了。
因为我们几乎无法去模拟真实的手算,因为无法试除,但想一想除法的本质,除法的本质其实就是多个减法,但如果我们循环相减的话实在太浪费时间了,计数就是一个麻烦的问题。

那要怎么办呢?仍然是对齐法,只不过这次我们把最高位对齐,其他位补0,就是相当于把除数乘以10的某次幂使数位对齐这样就减少了减法的次数,我们还可以继续优化,对齐之后乘以某个数使除数接近于被除数,大家可以试一下这个数最小是被除数的最高位除以除数最高位与1的和即 (a[0]-‘0’)/(b[0]-‘0’+1),而最大值为9,这样我们就能算出一个最接近与被除数的数,而除数乘上的这两个值(10的某次幂与这个数)相乘就是商的一部分,我们让被除数减去这个计算出来接近被除数的值,然后仍旧让原除数对齐,新被除数,依次循环直至运算结束,每次累加出来的和就是商。说着有些绕,大家手算一下就明白了。举个例子:8000/99,先对齐99→9900,然而8000-9900得0,结果累加为0 ,进行下一步,99→990,990乘以9~0之间某个值最接近8000,这个值为8,故为8000-990*8=80,商累加为0+8*10=80,新被除数为80,99→99,然而无法再减,最后结果为80.

五. 大数除一个整形数
完全模拟手算就可以,和大数加减差不多,主要为了特殊情况节约时间;

六. 大数幂
使用二分求幂的方法去计算,需要调用大数乘法,二分幂详见http://blog.csdn.net/tt2767/article/details/45479003

七. 大数求模
大数求模,原理就是对每一位循环利用同余定理
如果 C = A + B
那么C % mod =( A % mod + B % mod)%mod 成立

八. 大数阶乘
这个输入一个整型数就可以了,输出结果为大数形式,按位计算,结果存在字符串中就好,类似于大数加减

九. 大数比较
大数比较就很简单了,主要了对比长度,然后从高位到低位对比每一位就好

十. 一些需要注意的事
每一个运算中都存在这WA点可能使你的程序得到错误的结果,看看你是否注意到了下面的一些情况?
1. 特殊值的处理:当值为0或1的时候怎么处理?正值与负值怎么处理?
2. 每次运算是否都把结果保存了下来?
3. 新运算之前是否清空了保存结果的缓存区?
4. 需不需要增加前导0?需不需要删去前导0?进位时怎么处理?
5. 是否破坏了原始数据,有没有把原始数据拷贝或还原?
6. 是否考虑了每一步计算对后面产生的影响?
如果你能处理好这些问题,那么大数计算对你来说就不是问题了
大家可以先写一写自己的算法,然后按照后边的题自己测试一下,你写的正确与否,再查看模板,模板中已经详细注释了,请仔细查看!

**模板在最后,详细解析在模板的注释里面!!**

各大OJ上的练习题:
1.大数的加减乘除
加:hdu 1002A+B Problem II http://acm.hdu.edu.cn/showproblem.php?pid=1002
减:百炼2736 http://bailian.openjudge.cn/practice/2736/
乘:百炼2980 http://bailian.openjudge.cn/practice/2980/
除:百炼2737 http://bailian.openjudge.cn/practice/2737/
除法把主程序改成这样,其他的直接输入输出就好~

int main()
{
    char a[N] = {'\0'},b[N]={'\0'};
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s%s",a,b);
        puts(BigDivBig(a,b));
    }
    return 0;
}

2.hdu 1042 N!
http://acm.hdu.edu.cn/showproblem.php?pid=1042
把模版里的主程序改成这样就过了 =。=

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        puts(BigFuc(n));
    }
    return 0;
}

3.poj3982 序列
http://poj.org/problem?id=3982
再把主程序改成这样 =。=

int main()
{
    char ans[105][N] = {'\0'};
    char temp[N]={'\0'};
    int n,i;

    while(~scanf("%s%s%s",ans[0],ans[1],ans[2]))
    {
        for(i = 3 ; i <=99 ; i++)
        {
            strcpy(temp,BigAdd(ans[i-3],ans[i-2]));
            strcpy(ans[i],BigAdd(temp,ans[i-1]));
        }
        puts(ans[99]);
    }
    return 0;
}

4 . NYOJ 73 比大小
http://acm.nyist.net/JudgeOnline/problem.php?pid=73
改主程序。。。。。

int main()
{
    char a[N] = {'\0'},b[N]={'\0'};
    int n;

    while(scanf("%s%s",a,b))
    {
        n = BigCmp(a,b);

        if(n == 0 && a[0] == '0' && b[0] == '0')
            break;

        if(n == 0)
            puts("a==b");
        else if(n == 1)
            puts("a);
        else
            puts("a>b");
    }
    return 0;
}

5.NYOJ 45 棋盘覆盖 (递推 + 大数)
http://acm.nyist.net/JudgeOnline/problem.php?pid=45
可以算出公式为 f[i] = 4 * f[i-1] + 1,用大数打个表加快速度

套用模板后,增加增加代表4和0的大数并修改主程序:

int main()
{
    char four[2] = {'4','\0'};//增加代表4和0的大数
    char one[2] = {'1','\0'};

    char ans[105][N] = {'\0'};
    char temp[N]={'\0'};
    int n,i,k,Case;
    ans[1][0] = '1';
    ans[1][1] = '\0';

    for(i = 2 ; i <= 100 ; i++)
    {
        strcpy(temp,BigMul(ans[i-1],four));
        strcpy(ans[i],BigAdd(temp,one));
    }
    scanf("%d",&Case);
    while(Case--)
    {
        scanf("%d",&k);
        puts(ans[k]);
    }
    return 0;
}

6.hdu 1047 多组大数相加
http://acm.hdu.edu.cn/showproblem.php?pid=1047
这题表达的很乱,大致意思就是先输入一个整数代表数据组数,每组数据由0结尾,注意的是0后必有结果而且输出之间要有空行
这个模板因为是所以计算函数共用一个数组保存结果,故每以一计算都需要把结果保存下来!

int main()
{
    char a[N] = {'\0'},ans[N] = {'\0'};
    int Case;
    int i,j;

    scanf("%d",&Case);
    while(Case--)
    {
        ans[0] = '0';
        ans[1] = '\0';
        while(~scanf("%s",a))
        {
            if(strlen(a) == 1 && a[0] == '0')
                break;
            strcpy(ans,BigAdd(a,ans));
        }
        puts(ans);
        if(Case>0)
            puts("");
    }
    return 0;
}

7 . hdu1715 大菲波数
http://acm.hdu.edu.cn/showproblem.php?pid=1715
这个题和上边那个“棋盘覆盖”的题是一样的,只不过递推公式变了,其实还能更快求更大的斐波那契数(一亿多),只不过那需要用到矩阵递推了。

下面是我的模板,讲解都在注释里面了,仔细看!

#include//不能连续复合运算,要保存结果
#include//所以一个技巧就是用strcpy来代替等号
#include//c=a+b改写为strcpy(c,BigAdd(a,b))

#define BASE 10    //确定进制
#define N 90001    //确定 最大位数+1

int l = 0;                      //每次记录缓存区用了多长,还原时节省时间
char res[N] = { '\0' };  //保存结果

void ini(char * x , int l);   //初始化x数组
int BigCmp(char * a, char * b);  //  大数a < 大数b 返回1 ,相等返回0 ,a>b返回-1
void Clean(char * x, int l);//清除尾部的‘0’
void rev(char * x);//倒置字符串 ,与Clean联用,清除前导0

char * BigAdd(char * a, char * b);
char * BigSub(char * a,char * b);
char * BigMul(char * a,char * b);
char * BigDivNum(char * num,int  n);//大数除以一个int
char * BigDivBig(char * a,char * b);//大数除以一个大数

char * BigPow(char *num ,int n);
char * BigMod(char * num , int mod);
char * BigFuc(int num);

int main()
{
    char a[N] = {'\0'},b[N]={'\0'};
    int n;

    while(~scanf("%s%s%d",a,b,&n))
    {
        puts("a + b得:");
        puts(BigAdd(a,b));

        puts("a - b 得:");
        puts(BigSub(a,b));

        puts("a * b 得:");
        puts(BigMul(a,b));

        puts("a / b 得:");
        puts(BigDivBig(a,b));

        puts("a / n 得:");
        puts(BigDivNum(a,n));

        puts("a^n 得:");
        puts(BigPow(a,n));

        puts("a % n 得:");
        puts(BigMod(a,n));

        puts("n! 得:");
        puts(BigFuc(n));

        puts("");
    }
    return 0;
}

char *  BigAdd( char * a, char * b)
{
    int i,j,k;
    int sum,la,lb,carry,flag,cmp;
    char *ans,*temp;

    ini(res,l);
    carry = 0;
    flag = 0;
    ans = &res[1];

    if(a[0] == '-' && b[0] != '-')         //判断正负
        return BigSub(b,a+1);
    else if(a[0] != '-' && b[0] == '-')
        return BigSub(a,b+1);
    else if(a[0] == '-' && b[0] == '-')
    {
        flag = 1;
        a++;
        b++;
    }

    la=strlen(a);
    lb=strlen(b);

    if(b[0] == '0' && lb == 1)     //判断0
    {
        strcpy(ans,a);
        l = strlen(ans);
        return ans;
    }
    else if(a[0] == '0' && la ==1)
    {
        strcpy(ans,b);
        l = strlen(ans);
        return ans;
    }

    rev(a);
    rev(b);

    if(BigCmp(a,b) == 1)     //保持大数a>大数b
    {
        temp = a;
        a = b;
        b =temp;

        k = la;
        la = lb;
        lb = k;
    }

    for(i = lb ; i < la ; i++)  //空位补0
        b[i] = '0';

    for(i = 0 ; i < la ; i++)
    {
        sum = (a[i]-48) + (b[i]-48) + carry;

        if( sum < BASE )
        {
            ans[i] = sum + 48;
            carry = 0;
        }
        else
        {
            ans[i] = sum  - BASE  + 48;
            carry = 1;
        }
    }

    if(carry)   //补充最高位
    {
        ans[i] = carry + 48;
        i++;
    }

    Clean(ans,i);

    for(i = lb ; i < la ; i++)//删除后补上的0
        b[i] = '\0';

    rev(ans);
    rev(a);
    rev(b);

    if(flag)
    {
        res[0] = '-';
        ans = res;
    }

    l = strlen(ans);
    return ans;
}

char * BigSub(char * a,char * b)
{
    char *ans,*temp;
    int i,j,k;
    int borrow,flag,la,lb,sub,cmp;

    ini(res,l);
    ans = &res[1];

    flag = 0;  //结果没有负号
    borrow = 0;

    if(a[0]=='-' && b[0]!='-')  //被减数为负,减数为正,结果为负
    {
        BigAdd(b,a+1);
        res[0] = '-';
        return  res;
    }
    else if(a[0]!='-' && b[0]=='-') //被减数为正,减数为负,结果为正
        return BigAdd(a,b+1);
    else if(a[0]=='-' && b[0]=='-')   //如果a,b为同时负,交换他们并都改为正,保证为“a-b”的形式
    {
        temp=a;
        a=b;
        b=temp;

        a++;
        b++;
    }

    la = strlen(a);
    lb = strlen(b);

    if(b[0] == '0' && lb == 1)     //判断0
    {
        l = strlen(strcpy(ans,a));
        return ans;
    }
    else if(a[0] == '0' && la == 1)
    {
            if(b[0] == '-')
            {
                l = strlen(strcpy(ans,b+1));
                return ans;
            }
            else
            {
                res[0] = '-';
                l = strlen(strcpy(ans,b));
                return res;
            }
    }

    cmp = BigCmp(a,b);

    if(cmp == 0)
    {
        l = 1;
        res[0] = '0';
        res[1] = '\0';
        return res;
    }
    else if(cmp == 1)  //保持大数a>=大数b
    {
        temp=a;
        a=b;
        b=temp;
        flag=1;  //结果有负号

        k = la;
        la = lb;
        lb = k;
    }

    rev(a);
    rev(b);

    for(i=0; iif( sub >= 0)
        {
            ans[i] = sub + 48;
            borrow = 0 ;
        }
        else    // 溢出时的计算方法
        {
            ans[i]   = sub + BASE + 48;
            borrow = 1;
        }
    }

    while(i < la)   // 计算剩余位
    {
        sub = a[i] - borrow ;

        if(a[i] >= borrow)
        {
            ans[i]   = sub ;
            borrow = 0;
        }
        else        // 溢出时的计算方法
        {
            ans[i]  = sub +BASE ;
            borrow = 1;
        }
         i++;
    }

    Clean(ans,i);

    rev(ans);
    rev(a);
    rev(b);

    if(flag)
    {
        res[0] = '-';
        ans = res;
    }

    l = strlen(ans);
    return ans;
}

char * BigMul(char * a,char * b)
{
    char *temp,*ans;
    char mul[N] = {'\0'},cal[N] = {'\0'},num[N] = {'\0'};
    int i,j,k;
    int carry,flag,la,lb,product,lmul;
    int sign,sign_a,sign_b;

    ini(res,l);
    ans = &res[1];

    carry = 0;
    flag = 0;
    sign = sign_a = sign_b = 0;

    if(a == b)   //重复拷贝
        b = strcpy(num,a);

    if(a[0] == '-' )
    {
        flag = 1;
        sign_a = 1;
        a++;
    }
    if(b[0] == '-' )
    {
        flag = 1;
        sign_b = 1;
        b++;
    }
    if(sign_a && sign_b)
        flag = 0;

    la = strlen(a);
    lb = strlen(b);

    if((a[0] == '0' && la == 1) || (b[0] == '0' && lb == 1))  //任何一个大数为0,结果为0
    {
        l = 1;
        res[0] = '0';
        res[1] = '\0';
        return res;
    }

    if(BigCmp(a,b) == 1)   //保证大数a >= 大数b
    {
        temp = a;
        a = b ;
        b = temp;

        k = la;
        la = lb;
        lb =k;
    }

    rev(a);
    rev(b);

    Clean(a,la);//清除自带的前导0
    Clean(b,lb);
    la = strlen(a);//重新计算长度
    lb = strlen(b);

    lmul = 0;

    for(i = 0 ; i < lb ; i++)
    {
        ini(mul,lmul);

        for( j = 0 ; j < la ; j++)
        {
            product = (a[j] - 48) * (b[i] - 48) + carry ;
            mul[j] = product % BASE + 48 ;
            carry = product / BASE ;
        }

        if(carry)
        {
            mul[j] = carry + 48;
            j++;

            carry = 0;
        }

        lmul = j;  //计算缓冲区长度

        if(i == 0)
        {
            strcpy(cal,mul);
            rev(cal);
        }
        else
        {
            //清除前导0
            Clean(mul,lmul);
            //翻转字符串
            rev(mul);
            //以0补位,每次相当于乘10
            for(k = 0 ; k < i ;k++)
                mul[lmul++] = '0';
            //保存
            ans = BigAdd(cal,mul);
            ini(cal,strlen(cal));
            strcpy(cal,ans);
        }
    }
    strcpy(ans,cal);

    rev(a);
    rev(b);

    if(flag)
    {
        res[0] = '-';
        ans = res;
    }
    l = strlen(ans);
    return ans;
}

char * BigDivBig(char * a,char * b)
{
    char *ans, *temp;
    int i,j,k,la,lb,cmp,times,tran_min;
    int sign,sign_a,sign_b,flag;

    ini(res,l);
    ans = &res[1];
    sign_a = sign_b = flag = 0;

    if(a[0] == '-')
    {
        sign_a = flag = 1;
        a++;
    }
    if(b[0] == '-')
    {
        sign_b = flag = 1;
        b++;
    }
    if(sign_a && sign_b)
        flag = 0;
    la = strlen(a);
    lb = strlen(b);

    rev(a);
    rev(b);
    Clean(a,la);
    Clean(b,lb);
    rev(a);
    rev(b);

    la = strlen(a);
    lb = strlen(b);

    if(la == 1 && a[0] == '0')
    {
        l = 1;
        res[0] = '0';
        res[1] = '\0';
        return res;
    }
    if(lb == 1 && b[0] == '0')
    {
        puts("除数不能为0!");
        exit(1);
    }
    if(lb == 1 && b[0] == '1')
    {
        l = strlen(strcpy(res,a));
        return res;
    }

    cmp = BigCmp(a,b);
    if(cmp == 1)
    {
        l = 2;
        ans[0] = '0';
        ans[1] = '\0';
        return ans;
    }
    else if(cmp == 0)
    {
        l = 2;
        ans[0] = '1';
        ans[1] = '\0';
        if(flag)
        {
            res[0]='-';
            ans = res;
        }
        return ans;
    }
    ///对齐最高位试除
    char pre[N] = {'\0'},num[N] = {'\0'},now[N] = {'\0'},tran[N] = {'\0'};
    char mul[N] = {'\0'},sub[N] = {'\0'},div[N]={'\0'};
    char carry[N] = {'0'};///注意是 0
    memset(carry,'0',sizeof(carry));
    now[0] = '0'; //大数now初始化为0
    carry[0] = '1';//大数carry初始化为1000000000……
    times = la - lb;//确定最高倍数
    strcpy(num,a);  //复制a的值
    strcpy(div,b);//复制b的值
    for(i = 0 ; i < times ; i++) //对齐最高位
            div[lb+i] = '0';

    for(i = times ; i >= 0 ;i--)
    {   //最小的倍数为:a最高位/(b最高位+1),试一下就知道了
        tran_min = (num[0] - '0')/(div[0]-'0'+1);   ///?????
        for(j = 9 ; j >= tran_min ; j--)
        {
            sprintf(tran,"%d",j); //把试乘值转换成字符串
            strcpy(pre,BigMul(div,tran));
            strcpy(sub,BigSub(num,pre)); //sub = a - b*j;
            //从大到小找第一个可以被减的数
            if(sub[0] != '-')
            {
                carry[i+1] = '\0'; //截断carry得到倍数
                strcpy(mul,BigMul(carry,tran));//乘上这次的值
                strcpy(now,BigAdd(now,mul));//将商保存在now中
                strcpy(num,sub);   //更新a的值
                break;
            }
        }
        div[lb+i-1] = '\0'; //每次循环降低一位直至复原
        memset(res,'\0',sizeof(res));
    }
    strcpy(ans,now);
    if(flag)
    {
        res[0] = '-';
        ans = res;
    }
    l = strlen(ans);
    return ans;
}

char * BigDivNum(char * num , int n)
{
    char * ans;
    int i,j,digit,divis,lnum,flag;
    int sign_num,sign_n;

    ini(res,l);

    ans = &res[1];

    digit = divis = flag = 0;
    sign_num = sign_n = 0;

    if(n == 0)
    {
        puts("除数不能等于0");
        exit(1);
    }

    if(n < 0)
    {
        n = -n;
        flag = 1;
        sign_n = 1;
    }
    if(num[0] == '-')
    {
        num++;
        flag = 1;
        sign_num = 1;
    }
    if(sign_n && sign_num)
        flag = 0;

    lnum = strlen(num);

    if(lnum == 1 && num[0] == '0')
    {
        l = 1;
        res[0] = '0';
        res[1] = '\0';
        return res;        //被除数为0,结果为0
    }

    for(i = 0 ; i < lnum ; i++)
    {
        divis = divis * 10 + (num[i]-48) ;

        if(divis >= n)
        {
            ans[digit++] = divis / n + 48;
            divis %= n;
        }
    }

    if(!digit)
        ans[digit++] = '0';

    ans[digit] = '\0';

    if(flag)
    {
        res[0] = '-';
        ans = res;
    }
    l = strlen(ans);
    return ans;
}

char * BigPow(char * num, int n)
{
    char  * ans;
    char cal[N] = {'\0'},pow[N] = {'\0'};
    int  flag;

    if(n == 0)
    {
        l = 1;
        res[0] = '1';
        res[1] = '\0';
        return res;
    }

    if(strlen(num) == 1 && num[0] == '0')
    {
        l = 1;
        res[0] = '0';
        res[1] = '\0';
        return res;
    }

    ini(res,l);
    ans = &res[1];

    flag = 0;

    strcpy(pow,num); //备份
    cal[0] = '1';

    if(pow[0] == '-' && n&1)
        flag = 1;

    while(n)
    {
        if(n&1)
        {
            ans = BigMul(cal,num);

            ini(cal,strlen(cal));
            strcpy(cal,ans);
        }

        ans = BigMul(num,num);

        ini(num,strlen(num));
        strcpy(num,ans);

        n >>= 1;
    }
    strcpy(num,pow); //还原

    strcpy(ans,cal);
    if(flag)
    {
        res[0] = '-';
        ans = res;
    }
    l = strlen(ans);
    return ans;
}

char * BigMod(char * num , int mod)
{
    char * ans;
    int i,lnum,cal;

    if(mod == 0)
    {
        puts("除数不能等于0");
        exit(1);
    }

    ini(res,l);

    ans = &res[1];
    cal = 0;

    lnum = strlen(num);

    for(i = 0 ; i < lnum ; i++)     //循环利用同余定理
        cal = ( ((cal*BASE)%mod) + ((num[i]-48)%mod) ) % mod ;

    sprintf(ans,"%d",cal);  //转换为字符串
    l = strlen(ans);
    return ans;
}

char * BigFuc(int num)
{
    int i,j,k;
    int digit,carry,temp;
    char * ans;

    ini(res,l);
    ans = &res[1];

    if(num == 0)
    {
        l = 1;
        res[0] = '1';
        res[1] = '\0';
        return res;
    }

    ans[0] = '1';
    digit = 1;

    for(i = 2 ; i <= num ; i++)
    {
        carry = 0;  //初始化为0

        for(j = 0 ; j < digit ; j++)
        {
            temp = (ans[j]-48)* i + carry; //中间值

            ans[j] = temp % BASE +48 ;
            carry = temp / BASE;
        }

        while(carry)  //处理剩余位数
        {
            ans[digit++] = carry % BASE + 48;
            carry /= BASE ;
        }
    }

    rev(ans);

    l = strlen(ans);
    return ans;
}

int BigCmp(char * a, char * b)  //  大数a < 大数b 返回1 ,相等返回0 ,a>b返回-1
{
    int i,j,k;
    int la = strlen(a),lb = strlen(b);
    char * temp;

    if(a[0] == '-' && b[0] != '-')
        return 1;
    else if(a[0] != '-' && b[0] == '-')
        return -1;
    else if(a[0] == '-' && b[0] == '-')
    {
        a++;
        b++;

        temp = a;
        a = b;
        b = temp;

        la--;
        lb--;

        k = la;
        la =lb;
        lb = k;
    }

    if(la < lb)
        return 1;
    if(la > lb)
        return -1;

    if(la == lb)
    {
        for(i = 0 ; i < la ; i++)
        {
            if(a[i] < b[i])
                return 1;
            else if(a[i] > b[i])
                return -1;
        }
    }

    return 0;
}

void ini(char * x ,int l)
{
    int i;

    if(l < N)
        l++;

    for(i = 0 ; i < l ;i++)
        x[i] = '\0';
}

void Clean(char * x,int l)
{
    for(l--; x[l] == '0';l--)
        x[l] = '\0';
}

void rev(char * x)
{
    int right = strlen(x)-1;
    int left = 0;
    char temp;

    while(left < right)
    {
        temp = x[left];
        x[left++] = x[right];
        x[right--] = temp;
    }
}

你可能感兴趣的:(ACM_大数运算&&高精度)