szuoj b47 有符号大整数加减法

题意很简单:

输入两个整数A和B(范围均为10的-1000次方到10的1000次方之间)。

输出A+B,和A-B。

题目有一点没有讲清楚,就是要去掉前导0,即

-000000也是0

-00001是-1

000000是0

00001200是1200

因为不知道这个,WA了好多次


最后的版本:

全部思路:

(1)写出大整数加法和减法函数,其中减法函数仅仅可以处理一个大的数减去一个小的数

(2)读入两个大整数到Atmp和Btmp,对于Atmp和Btmp作预分析,然后再放入数组A和B(相当于预处理)

这个过程容易出错:

1)由于需要进行分类(按题目输入的两个整数其正负情况分:1(+ +) 2(- -) 3(+ -) 4(- +)四类),

即可以转换为:两个数相加或大数减小数的情况,最后根据情况决定是否在前面添加负号

2)但是比如输入-000和-00000,本质是两个0,却被认为是情况2,在情况2中,-10 + (-10)结果为-20,而-0 + (-0)却不能输出为-0

此时,应该先确定“有效部分”(除了负号和前导0),如果有效部分是0,那么不管是输入的是-0000还是00000,都把第一位元素修改为'0'

确定“有效部分”,即确定“有效部分”的开始指针(指向第一个元素)和结束指针(指向最后一个元素的下一个位置)

3)处理完上述情况后,进行分类(不再有-000这种傻逼情况了)

4)在放入数组A和B之前,先判断“有效部分”的谁代表的整数更大!设定Abigger,若A>B ,则Abigger > 0,若A==B,则Abigger = 0,若A<B,则Abigger < 0

5)逆序地把Atmp和Btmp导入数组A和B

6)返回A和B长度的最大值

(3)写一个函数根据预分析时得到的结果,按其符号决定的类型进行分支处理(求和,求差)!

当然,这里用了6个数组,主要是考虑尽量简单地实现(KISS)。其实3个数组就够了。2个char数组找到有效部分后可以反转,

但加法和减法函数需要略修改,传入开始指针和结束指针,一个int数组保存加法结果和减法结果(做完加法后直接根据len来高效清空,再做减法),这样效率甚至还有提升。

#include <stdio.h>
#include <string.h>
#define N 12000
char Atmp[N];
char Btmp[N];
char A[N];
char B[N];
int AaddB[N];
int AsubB[N];
int caseNo;
int Abigger;

void add(int len)
{
	int i, gap = 2*'0';
	for (i = 0; i != len; AaddB[i++] = A[i]+B[i]-gap) NULL;
	for (i = 0; i != len; i++) {
			if (AaddB[i] > 9) {
                AaddB[i+1] += AaddB[i]/10;
                AaddB[i] %= 10;
            }
	}
	if (0 == AaddB[i])
		--i;
	for (; i != -1; printf("%d", AaddB[i--])) NULL;
	printf("\n");
}

void sub(int len)
{
	int i;
	if (Abigger > 0)
		for (i = 0; i != len; AsubB[i++] = A[i]-B[i]) NULL;
	else
		for (i = 0; i != len; AsubB[i++] = B[i]-A[i]) NULL;
	for (i = 0; i != len; i++) {
			if (AsubB[i] < 0) {
                AsubB[i+1] -= 1;
                AsubB[i] += 10;
            }
	}
	while (0 == AsubB[i])
		i--;
	for (; i != -1; printf("%d", AsubB[i--])) NULL;
	printf("\n");
}

int pre_process()
{
	int Abegin = 0, Aend = strlen(Atmp), Alen;
	int Bbegin = 0, Bend = strlen(Btmp), Blen;
	int i, len, Amark = 0, Bmark = 0;
	for (i = 0; i != Aend; i++)
		if (Atmp[i] > '0') {
			Abegin = i;
			Amark = 1;
			break;
		}
	if (Amark == 0) {
		Aend = 1;
		Atmp[0] &#
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值