【洛谷】P1601 A+B Problem(高精)两种解法 补充新的代码

【洛谷】P1601 A+B Problem(高精)

在这里插入图片描述

写法一

#include<bits/stdc++.h>
using namespace std;
string stra,strb;
int c[510];
int main(){
	//一、读入 
	cin>>stra>>strb;
	//二、补成一样长 
	while(stra.length()>strb.length()){
		strb='0'+strb;
	}
	while(stra.length()<strb.length()){
		stra='0'+stra;
	}
	//三、计算 
	int len=stra.length(),jin=0; 
	for(int i=len-1;i>=0;i--){
			c[i]=stra[i]-'0'+strb[i]-'0'+jin;
			jin=c[i]/10;
			c[i]=c[i]%10;
	}
	//四、输出 (考虑有多个0的情况)
	if(jin){//若加到最后一位产生进位,输出进位 
		printf("%d",jin);
		for(int i=0;i<len;i++) printf("%d",c[i]);
	}else{
		int flag=0,flag1=0;
		for(int i=0;i<len;i++){
			if(c[i]==0 && flag1==0){
				flag=1;
			}else{
				flag=0;
				flag1=1;
			}
			if(flag == 0) printf("%d",c[i]);
		} 
		if(flag==1) printf("0");//都是零 
	} 

	return 0;
}

```c
在这里插入代码片

思考点:

输入会从在000+0的这种情况,所以存在计算出的c[i]全是0的情况,刚一开始想过用异或做,ans=ans^c[i],if(ans==0) printf(“0”)一部分可以过,但是对于数据123+123会出错,返回2460,因为异或的的中间结果会和操作数相等,导致出现零。

写法二

#include<bits/stdc++.h>
using namespace std;
string a,b,c;
int dw,jin;
int main(){
	cin>>a>>b;
	//一、读入,把两个数组补成一样长 
	while(a.length()>b.length()){
		b="0"+b;
	}
	while(a.length()<b.length()){
		a="0"+a;
	}
	//二、相加计算 
	for(int i=a.length()-1;i>=0;i--){
		dw=a[i]-'0'+b[i]-'0'+jin;
		jin=dw/10;
		dw=dw%10;
		c=char(dw+'0')+c;
	}
	if(jin) c=char(jin+'0')+c;
	//三、输出(判断前导0) 
	int flag=0,flag1=0;
	for(int i=0;i<c.length();i++){
		if(c[i]=='0' && flag1==0){
			flag=1;
		}else{
			flag=0;
			flag1=1;
			cout<<c[i];
		}
	}
	if(flag) cout<<"0"; 	
	
	return 0;
}

判断前导零方法:

//三、输出(判断前导0) 
	int flag=0,flag1=0;
	for(int i=0;i<c.length();i++){
		if(c[i]=='0' && flag1==0){
			flag=1;
		}else{
			flag=0;
			flag1=1;
			cout<<c[i];
		}
	}
	if(flag) cout<<"0";

给定一个变量flag,初值为0,假设判断的数字里一开始不存在0,如果遇到0,就把flag置为1;但是会存在第一个是0,后面是其他数字,然后再是0的这种情况(比如001201),但是要不输出的只是第一个非0数字前面的0,一旦遇到其他数字时,就不再判断(其他数字后面的0也要输出),所以设置一个变量flag1,初值为0,代表这个数字只有0,所以if条件判断是两个条件联合,一旦出现不是0的数字,就把flag1置成1,代表这个数字里有其数非0数字,就不需要再判断0了,于是if条件不会再进,在else中输出每个数字。
对于全是0的数字,只需要判断flag是否为1,是1的话,则说明这个数字全是0,所以当把这个数字的全部数位判断完,即在for循环外面,输出1个0即可,表示这个数字是0.

补充新的代码2022-2-4

(1)补充写法1

#include<bits/stdc++.h> 
using namespace std;
string s1, s2; //存放输进来的数据 
int a[510], b[510], c[510], r;
void duiqi(string s, int len, int s_len, int arr[]) {
	for (int i = s_len - 1; i >= 0; i--) {
		arr[len - 1] = s[i] - '0';
		len--;
	}
	//数组元素从0对齐改为从最后一个对齐,原先数组长度不够,前面为补0 ,不用把数组翻过来
}
void jiafa(int len) {
	for (int i = len - 1; i >= 0; i--) {
		int num = a[i] + b[i] + c[i];
		c[i] = num % 10;
		if (i - 1 < 0) {
			r = num / 10;
		}else{
			c[i - 1] = num / 10;
			//整型数组下标出现负数或者大于n-1不一定报错,特判一下 
		}
	}
}
void output(int len, int l1, int l2) {
	//最后一位有进位 
	int i = 0;
	if (r != 0) printf("%d", r);//输出进位,再输出后面的数 
	else {
		while(c[i] == 0 && i != len - 1) i++;
		//去除前导0,最后一位无论是0还是其他数字都要正常输出 
	} 	
	//输出第一个不是0的及后面的数,存在只有一个数的情况,可能是0
	for (int j = i; j < len; j++) 
		printf("%d", c[j]);	
}
int main() {
	cin >> s1 >> s2;
	int len, s1_len = s1.length(), s2_len = s2.length();
	len = (s1_len >= s2_len)? s1_len : s2_len;
	//1.对齐 
	duiqi(s1, len, s1_len,a);
	duiqi(s2, len, s2_len,b);
	//2.相加:加数+加数+进位   
	jiafa(len);
	//3.输出,要考虑最后一位有进位的情况,超出了下标0 
	output(len, s1_len, s2_len);
	
	return 0;
} 
```cpp


```c
在这里插入代码片

(2)写法2


#include<bits/stdc++.h>
#define mmax 520
using namespace std;
int a[mmax], b[mmax], c[mmax];
int main() {
	string m, n;
	cin >> m >> n;
	//1.对齐 
	int len = max(m.length(), n.length());
	for (int i = m.length() - 1, j = 1; i >= 0; i--, j++) {
		a[j] = m[i] - '0';
	} 
	for (int i = n.length() - 1, j = 1; i >= 0; i--, j++) {
		b[j] = n[i] - '0';
	}
	//2.加法计算 
	for (int i = 1; i <= len; i++) {
		int num = a[i] + b[i] + c[i];
		c[i + 1] = num / 10;
		c[i] = num % 10;
	}
	//3.输出处理,考虑最后一位会进位 ,前导0 
	if (c[len + 1] != 0) {//是否产生进位 ,有进位不用考虑前导0 
		len++;
	}else {
		while(c[len] == 0 && len != 1) len--;
		//while(!c[len] && len != 1) len--; //也可用这种写法 
		//前导0,从最后一位开始判断,如果对应的元素是0,长度就相应的减1,因为是倒序输出 
	} 
	for (int i = len; i >= 1; i--) {
		cout << c[i];
	}
	//无论如何,都会输出最后一个 
	
	return 0;
}

问题记录异常值3221225477:

1、返回异常值3221225477
访问越界,一般是读或写了野指针指向的内存

	int i;
	if (c[len + 1] != 0) {
		i = len + 1;
	}
	cout<<"i:" << i << endl;
	for (int j = i; j >= 1; j--) {
		cout << c[i];
	}

在这里插入图片描述
如果c[len+1]为0的话,也就是没有产生进位,那么i有没有赋初值,所以系统胡乱给了一个值,运行结果可以看出,这个时候再去访问以i为下标的数组元素,内存就会报错,可以让i的初值为len,如果有进位那就i++,然后再输出。这么做有些麻烦,直接让len的值加就可以。写代码的过程中遇到的问题比较有趣,就记录下来。

可以的写法

if (c[len + 1] != 0) {
		len++;
	}//是否产生进位 
	for (int i = len; i >= 1; i--) {
		cout << c[i];
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值