题意很简单:
输入两个整数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] &#