洛谷P1601 a+b高精计算 超详解释

文章讲述了如何使用C++编程语言,通过字符串形式读取数字,将字符数组中的每位转换为十进制并相加,同时处理进位问题,以实现两个数字的正确相加。关键点包括字符串的补零操作、字符转数字、以及从低位到高位的逐位相加和进位逻辑。

思路:

使用字符串的形式读取输入的数字,(字符串可看为字符数组),将字符数组中的每一位转换为对应的十进制数字,将两个字符数字的对应位相加即可。

AC代码:

#include<iostream>
#include<cstring>
using namespace std;

const int MAXN=1e5+5;
int main(){
	
	string m1="0";
	string n1="0";
	cin>>m1;//以字符串的形式读取数字
	cin>>n1;
	int m[MAXN]={0};
	int n[MAXN]={0};//将读取到的各位字符转换为数字储存在m,n数组中
	int lth1=m1.length();
	int lth2=n1.length();
	int lth=max(lth1,lth2);
	m1.insert(0,lth-lth1,'0');
	n1.insert(0,lth-lth2,'0');
	int arr[MAXN]={0};
	for(int i=lth-lth1;i<lth;i++){
		m[i]=m1[i]-'0';
	}
	for(int i=lth-lth2;i<lth;i++){
			n[i]=n1[i]-'0';
	}
	for(int i=lth-1;i>=0;i--){
		arr[i]+=m[i]+n[i];

		//考虑进位
		if(arr[i]>=10&&i!=0){
			arr[i-1]+=(arr[i]/10);
			arr[i]=arr[i]%10;
		}
	}

	for(int i=0;i<lth;i++){
			cout<<arr[i];
	}
	return 0;
}

可能出现的问题:(对所有出现的数组都初始化为0)

  1. 对应位相加会导致:可能不是真实的对应位(是指个位和个位相加,十位和十位相减……)相加,如输入56和120,就会出现(5+1)(6+2)和(0+0),因为计算机只知道56的第0位是5、120的第0位是1,那就进行5和1的加法运算(它不知道啥是数学中的个位、十位)。所以要对两个位数不同的数进行前面补0
  2. 两个数相加的和大于等于10,会导致某一位输出两位数,进而导致总结果不正确,如输入12和28会输出310(从后面开始加)。所以要考虑进位,从数学中的个位开始加,遇到大于10的数,用a[i-1]+=a[i]/10进位,进而该位变成a[i]=a[i]%10。but仍有问题:首位相加,遇到大于10的数,如果还进行上述操作会导致首位只输出一位数【一进位,导致首位变成两个数,而再程序中一般是要限制输出的个数(循环有条件)】,如输入1001和9099,输出0100,解决方法:让首位不进行上述操作,直接输出
  3. 问题1中“补0”后每个数总位数都和最大数的总位数保持一致,21和24行循环进行的条件是i<lth,而非是各个字符数组对应的输入的长度(“补0”后长度发生了变化)
  4. 获取字符串的长度,用length,不能用strlen,strlen不能直接求string类字符串长度,必须先转换为char类型的数组(为了简单行事,直接用length很香)

解决:

  1. 定义两个字符串m1,n1,来读取输入的数字;定义三个int型数组,其中两个来保存对应位相加所得的结果,另一个储存对应位相加的结果(当然也可以只用两个数组,将第二个数组加到第一个数组中)
  2. 18-19行:“补0”操作。用insert函数,insert( index : int , n : int , ch : char ) : string表示将n个ch字符插入本字符串下表index处。下图为上述程序使用的insert函数的一些简短的介绍
string s1("AA")
s1.insert(1,4,'B');
cout<<s1<<endl;//s1 becomes to ABBBBA

进行15和16行的操作后,每个字符数组的前面都有lth-lth1或lth-lth2位'0'

  1. 21-26行:将对应的字符转换为十进制的int型数据。从lth-lth1或lth-lth2开始进行,直到第lth-1位,将每一个数字字符转换为十进制数字,进行减字符0操作
  2. 27-35行:开始运算。从个位开始加,即从第lth-1位开始加。31-34行:考虑进位,注意第32行进位是将第i位相加得到两位数的十位加到第i-1位上【arr[i-1]+=(arr[i]/10)】,而不是加到第i+1位上,因为前面第一个是第0位(越在前面,位数越小)。且第0位不仅不进行进位,进位了就没办法完整输出了
  3. 37-39行:输出。

本文仅是我的一些“拙见”,如有失误,还请各位再评论区说明

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值