关于高精度加法

关于高精度加法

题目:

由键盘输入两个位数很长的整数(一行一个,最多不超过80位),试计算并输出这两个数的和。

输入样例

1234567890123456789353534532453453453434534
987654321098765324534534534534532

输出样例

1234567891111111110452299856987987987969066

引入
学过 C C C语言的我们,对于普通的加法当然会算,就是简单的输入 a a a b b b,然后输出 a + b a+b a+b就行

#include <stdio.h>
int main()
{
   int a, b;
   scanf("%d%d",&a, &b);
   printf("%d\n",a + b);
   return 0;
}

那么,当 a a a的值很大很大,且b的值也很大很大的时候呢?

就是当 a a a 1234567890123456789353534532453453453434534 1234567890123456789353534532453453453434534 1234567890123456789353534532453453453434534
b b b 987654321098765324534534534534532 987654321098765324534534534534532 987654321098765324534534534534532
时。

相信大家一开始看到这一长串的数字,肯定都蒙了吧!
正常一个普通的变量是存不了 10 10 10几位的数字的。
那么这时候我们应该怎么解决这样的问题呢?
没错,这时候就要用上我们所学的数组了,但要记住,不是单纯的数组,是字符串数组和普通数组一起使用。下面一步一步的进行讲解。

大数在字符串数组是怎样存取的

在这里插入图片描述

将字符转化为整形数字存入数组

这里要记住一定要倒序存储,字符数组存储的是字符对应的ASCII码,所以当我们将字符转化为数字时要减去 0 0 0**或者 48 48 48 0 0 0对应的 A S C I I ASCII ASCII码)

    int i,j,k,len1,len2,len;
    char k1[100],k2[100];
    int m1[100],m2[100],m[101];/*这里建立三个整形数组,其中两个存取大整数,另外一个存取两个数相加后的大整数*/
    //因为我们最后一位有可能需要向下一位进1,所以我们建立数组的时候,存取结果的数组要比存取加数的要多一位,才能保证最后不会越界。
    scanf("%s",k1);
    scanf("%s",k2);
    len1=strlen(k1);//"strlen"是一个计算字符串长度的函数 
	len2=strlen(k2);//将输入的两个字符串的长度赋值给len1,len2 
    for(i=0; i<len1; i++)
    {
        m1[i]=k1[len1-1-i]-'0';//很常规的倒序存储,一定要记得减'0'
    }
    for(i=0; i<len2; i++)
    {
        m2[i]=k2[len2-1-i]-'0';
    }

经过倒序存储后, 123456789 123456789 123456789就会变成“ 987654321 987654321 987654321”存进数组中

接下来是最重要的就是计算

记住一个最重要的原则“满10向下一位进1”
比如 23456789 + 98765432 23456789+98765432 23456789+98765432
因为已经倒序存过数字了,所以直接从最高位开始计算,即 2 + 9 = 11 2+9=11 2+9=11;这时候因为已经满 10 10 10了,所以我们要向下一位进 1 1 1,即当我们计算下一位的时候最后要加上1,并且该位要 − 10 -10 10;若未满 10 10 10,就保留数字即可,并且将数字存进一个新的数组。
最后依次计算可得两数之和为 122222221 122222221 122222221

  	if(len2>=len1)
    {
        for(i=len2; i<len2; i++)
        {
            m1[i]=0;
        }
        len=len2;
    }
    k=0;//这里的k是指是否要向下一位进1,k=0为不需要进1,k=1为需要
    for(j=0; j<len; j++)//依次进行每一位的加法,满十进一
    {
        m[j]=m1[j]+m2[j]+k;
        if(m[j]>=10)//判断是否需要向下一位进1
        {
            k=1;
            m[j]=m[j]-10;
        }
        else
        {
            k=0;
        }
        if(j==len-1&&k==1)//这里,如果已经计算到最后一位了,且这时需要进一,我们便往下一位填1即可
        {
            j++;
            m[j]=k;
        }
    }
    for(i=j-1; i>=0; i--)//最后再倒序输出新数组内的数字即为最后的结果
    {
        printf("%d",m[i]);
    }
}

完整解题代码

#include <stdio.h>
#include <string.h>
int main()
{
    int i,j,k,len1,len2,len;
    char k1[100],k2[100];
    int m1[100],m2[100],m[101];
    scanf("%s",k1);
    scanf("%s",k2);
    len1=strlen(k1);
    len2=strlen(k2);
    for(i=0; i<len1; i++)
    {
        m1[i]=k1[len1-1-i]-'0';
    }
    for(i=0; i<len2; i++)
    {
        m2[i]=k2[len2-1-i]-'0';
    }
    if(len1>len2)
    {
        for(i=len2; i<len1; i++)
        {
            m2[i]=0;
        }
        len=len1;
    }
    if(len2>=len1)
    {
        for(i=len2; i<len2; i++)
        {
            m1[i]=0;
        }
        len=len2;
    }
    k=0;
    for(j=0; j<len; j++)
    {
        m[j]=m1[j]+m2[j]+k;
        if(m[j]>=10)
        {
            k=1;
            m[j]=m[j]-10;
        }
        else
        {
            k=0;
        }
        if(j==len-1&&k==1)
        {
            j++;
            m[j]=k;
        }
    }
    for(i=j-1; i>=0; i--)
    {
        printf("%d",m[i]);
    }
}

总结

高精度加法是一个很有难度的题,并且会延伸出类似于二进制加法,甚至八进制加法的题目,所以一定要总结规律,以后类似的题目就能迎刃而解了。

希望大家看完该篇文章之后,以后再一次遇上类似高精度加法的题目,能顺利 A C AC AC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值