大整数加法可谓是学习C++语言的一个里程碑。那么,如何在C++简单易懂地实现大整数加法呢?
概念思路
假定这两个十进制的大整数位数不超过255位。
那么,可以定义两个长度为255的字符数组(num1,num2),以换行符作为分界线,依次读入。
最后,从两个数组的最后一位开始,一位位地向前相加,进位,直到两个数组都被读完或一个数组被读完(此时,更长的一个数组剩下的数字直接输出)。
例如:
num1[5]={'1','2','3','4','5'};
num2[5]={'2','3','4','5','6'};
定义减数i=0,while(i<=strlen(num1)&&i<=strlen(num2))时,对[长度-i-1]所对应的那一个数字进行操作。
如果,两数长度不一的话:
num1[5]={'1','2','3','4','5'};
num2[2]={'5','6'};
那么在i=3的时候,i<strlen(num2)将为false,跳出循环。
字符的相加
先来了解一下二字符相加的结果(ASCII码,已知者可跳过)。
不仅是在C++中,每个字符在ASCII下都对应着一个数字。比如说,97表示'a',65表示'A',48表示'0'。
在本例中,用到的是字符'0'-'9',对应的数字也就是48-57。
若有两个字符a和b,a='0',b='0',
那么,a+b返回的结果就是48+48=96(因为'0'是48)。若想使结果的ASCII总和就是数字之和,那么显而易见,应该再减去96。
在这个操作后,
'9'+'0'=57+48=105,减去96就是9,即9+0;
'4'+'4'=52+52=104,减去96就是8,即4+4。
至于进位,'9'+'9'=57+57=114,减去96就是18,即9+9,此时应检测到总和大于9,应保留总和-10(8),并向前进一位。
那么,可以实现在一个函数里:
int plusn(char a,char b)
{return int(a+b-96);}
简单吧?
字符串的读入
经过专业的cin输入流读入和puts(char[])的检测,发现cin是可以直接输入字符串的。
即:
char num1[255]={'\0'},num2[255]={'\0'};
cin>>num1>>num2;
没毛病。
代码初步实现
//作者:翼城朝雨;未经授权,请勿复制!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char number1[255]={'0'},number2[255]={'0'};
int sum[255]={0},i=1;
int plusn(char a,char b)
{
return int(a+b-96);
}
int main()
{
cin>>number1>>number2;//输入数组
int len1=strlen(number1),len2=strlen(number2);
while(i<=min(len1,len2))
{
sum[255-i]+=plusn(number1[len1-i],number2[len2-i]);
if(sum[255-i]>=10)
{
sum[254-i]++;
sum[255-i]-=10;
}
i++;
}
if(i<=len1)
{
while(i<=len1)
{
sum[255-i]+=number1[len1-i]-48;
if(sum[255-i]>=10)
{
sum[254-i]++;
sum[255-i]-=10;
}
i++;
}
}
else if(i<=len2)
{
while(i<=len2)
{
sum[255-i]+=number2[len2-i]-48;
if(sum[255-i]>=10)
{
sum[254-i]++;
sum[255-i]-=10;
}
i++;
}
}
while(i>1)
{
i--;
cout<<sum[255-i];
}
return 0;
}
思路:
1.输入2个字符串
2.从后向前逐位相加
3.检测:两数是否位数不同,若有,则将长的一个数字剩下的数直接调入sum[]数组
4.倒过来逐位输出
编译测试结果:
有问题。经典型例子检测,发现需要特别考虑输入为"1"和"01"(输出为"02",有前导0)
代码修改1
修改目标:
进行前导0检测
修改思路:
建立变量q,赋初值0;
输出的时候,检测到非0的数字,q=1,允许接下来输出。
可以把它理解成输出闸门,q=0时闸门关闭,q=1时闸门开启。
代码实现:
while(i>1)
{
i--;
if(sum[255-i]!=0&&q==0)q=1;
if(q==1)cout<<sum[255-i];
}