您的位置:首页 > 其它

高精度计算-大整数加减法

2015-05-04 10:22 316 查看

问题描述

求两个不超过 200 位的非负整数的和。

输入数据

有两行,每行是一个不超过 200 位的非负整数,没有多余的前导 0。

输出要求

一行,即相加后的结果。结果里不能有多余的前导 0,即如果结果是 342,那么就不能

输出为 0342。

输入样例

22222222222222222222

33333333333333333333

输出样例

Output Sample:

55555555555555555555

解题思路

C/C++中的 int 类型能表示的范围是[−231-2^{31},−231–1-2^{31} – 1]。

unsigned 类型能表示的范围是 [0,232−12^{32}-1]。所以,int 和 unsigned 类型变量,都不能保存超过 10 位的整数。( 10x<=232−1,x<=9.6310^x <= 2^{32}-1,x<=9.63)。参与运算的数如果大于10位数,基本数据类型已经无法表示。基本思想是:用数组模拟大整数,一个数组元素,放一位整数。不过一个数组元素存一位,空间上有点浪费,那么节省空间,可以一个数组存多位,比如说4位,注意的是进位的时候,这个时候的进位不再是10,而是10000。

代码实现

基本方法

[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 200
int x[MAX_LEN + 20], y[MAX_LEN + 20], z[MAX_LEN + 20];
char a[MAX_LEN + 20], b[MAX_LEN + 20];

void char_to_int(const char s[ ], int x[ ])
{
    int i = 0;
    int len = strlen(s);

    memset(x,0,MAX_LEN + 20);  
    int j  = 0;
    for(i = len - 1; i >= 0; i--)
    {
        x[j++] = s[i] - '0';
    }
}

void big_int_add(const int x[], const int y[], int z[])
{
    int i = 0;
    memset(z,0,MAX_LEN + 20);  

    for(i = 0; i < MAX_LEN; i++)
    {
        z[i] += x[i] + y[i];
        if(z[i] >=10)
        {
            z[i] = z[i] - 10;
            z[i+1] ++; 
        }
    }
}

void big_int_print(const int z[])
{
    bool flag = 0;
    int i = 0;

    for(i = MAX_LEN; i >=0; i--)
    {
        if(flag)
            printf("%d",z[i]);
        else if(z[i])
        {
            printf("%d",z[i]);
            flag = 1;
        }
    }

    if(!flag)
        printf("0");
    printf("\n");
}

int main( )
{
    scanf("%s",a);
    scanf("%s",b);

    char_to_int(a,x);
    char_to_int(b,y);

    big_int_add(x,y,z);

    big_int_print(z);

    return 0;

}


方法二

[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define Radix_Len  4
#define  Carry_num  10000
#define MAX_LEN  (200 / Radix_Len + 1)
int x[MAX_LEN], y[MAX_LEN], z[MAX_LEN + 1];
char a[MAX_LEN ], b[MAX_LEN ];

void char_to_int(const char s[ ], int x[])
{
    int i = 0;
    int len = strlen(s);

    memset(x,0,MAX_LEN);  
    int j  = 0;
    for(i = len; i > 0; i -= Radix_Len)
    {
        int tmp , k ;
        tmp = 0;
        const int low = i - Radix_Len > 0 ? i - Radix_Len : 0;
        for(k = low; k < i; k++)
            tmp = tmp * 10 + ( s[k] - '0');
        x[j++] = tmp;
    }
}

void big_int_add(const int x[], const int y[], int z[])
{
    int i = 0;
    memset(z,0,MAX_LEN);  

    for(i = 0; i < MAX_LEN; i++)
    {
        z[i] += x[i] + y[i];
        if(z[i] >=Carry_num)
        {
            z[i] = z[i] - Carry_num;
            z[i+1] ++; 
        }
    }
}

void big_int_print(const int z[])
{
    bool flag = 0;
    int i = 0;

    for(i = MAX_LEN; i >=0; i--)
    {
        if(flag)
            printf("%d",z[i]);
        else if(z[i])
        {
            printf("%d",z[i]);
            flag = 1;
        }
    }

    if(!flag)
        printf("0");
    printf("\n");
}

int main( )
{
    scanf("%s",a);
    scanf("%s",b);

    char_to_int(a,x);
    char_to_int(b,y);

    big_int_add(x,y,z);

    big_int_print(z);

    return 0;

}


题目来自 OpenJudge 百练 http://bailian.openjudge.cn/practice/2981/

大整数减法

[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 200
int x[MAX_LEN + 20], y[MAX_LEN + 20], z[MAX_LEN + 20];
char a[MAX_LEN + 20], b[MAX_LEN + 20];

void char_to_int(const char s[ ], int x[ ])
{
    int i = 0;
    int len = strlen(s);

    memset(x,0,MAX_LEN + 20);  
    int j  = 0;
    for(i = len - 1; i >= 0; i--)
    {
        x[j++] = s[i] - '0';
    }
}

void big_int_sub(const int x[], const int y[], int z[], int max_len)
{
    int i = 0;
    memset(z,0,MAX_LEN + 20);  

    int exchange = 0;

    printf("%d %d\n",x[max_len - 1],y[max_len - 1]);

    if(x[max_len - 1 ] < y[max_len - 1])
    {
        exchange = 1;
        printf("-");
    }
    for(i = 0; i < MAX_LEN; i++)
    {
        if(exchange)
        {
            z[i] += y[i] - x[i];
        }
        else
        {
            z[i] += x[i] - y[i];
        }

        if(z[i] < 0)
        {
            z[i] = z[i] + 10;
            z[i+1] --; 
        }
    }
}

void big_int_print(const int z[])
{
    bool flag = 0;
    int i = 0;

    for(i = MAX_LEN; i >=0; i--)
    {
        if(flag)
            printf("%d",z[i]);
        else if(z[i])
        {
            printf("%d",z[i]);
            flag = 1;
        }
    }

    if(!flag)
        printf("0");
    printf("\n");
}

int main( )
{
    scanf("%s",a);
    scanf("%s",b);

    int max_len = 0;
    int len1  = strlen(a);
    int len2  = strlen(b);

              max_len = len1 > len2 ? len1: len2;

    char_to_int(a,x);
    char_to_int(b,y);

    big_int_sub(x,y,z,max_len);

    big_int_print(z);

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: