51Nod-1005-大数加法
今天遇见一道细节问题特别多的题,写得我眼疼,题本身不难,难得是他的细节问题繁多,需要考虑的情况也甚多,稍有不慎就侧漏了,哈哈。
题的思路也很清晰,就是将最后的结果的正负的符号分离出来,剩下的就是高精度的加减法了,利用字符串处理即可,效率可以很高很高,有多高呢?自己感觉吧!
题:
给出2个大整数A,B,计算A+B的结果。
Input
第1行:大数A
第2行:大数B
(A,B的长度 <= 10000 需注意:A B有可能为负数)
Output
输出A + B
Input示例
68932147586
468711654886
Output示例
537643802472
题寥寥数行,看着很简单,其实思路真的很简单,但是我这粗心鬼,整整做了一个小时,因为自己粗心,总是忽略了很多的细节问题,频频出错,好在最后都改正了过来,代码如下。
代码C:
#include <stdio.h>
#include <string.h>
#define _MAX 10005
int product[_MAX] = {
0};
char numOne[_MAX] = {
0}, numTwo[_MAX] = {
0};
char numOneUp[_MAX] = {
0}, numTwoUp[_MAX] = {
0}; //倒序存储位置
int absMax = 1;
//递归进位函数
void Carrying(int tag, int i, int *p)
{
p[i] += tag;
if (p[i] > 9)
{
tag = 1;
p[i] -= 10;
Carrying(tag, i + 1, p); //写成Carrying(tag, i, j+1, p);也成立,为了让i+j递增而已
}
return ;
}
//递归退位函数
void Abdicate(int tag, int i, int *p)
{
p[i] += tag;
if (p[i] < 0)
{
tag = -1;
p[i] += 10;
Abdicate(tag, i + 1, p);
}
return ;
}
//判断大小
void size(int numOneLen, int numTwoLen)
{
int i, j;
if (numOneLen < numTwoLen)
{
absMax = 2;
for (i = 0; i < numTwoLen; i++)
{
numOneUp[i] ^= numTwoUp[i];
numTwoUp[i] ^= numOneUp[i];
numOneUp[i] ^= numTwoUp[i];
}
return ;
}
if (numOneLen == numTwoLen)
{
for (i = numOneLen - 1; i >= 0; i--)
{
if (numOneUp[i] < numTwoUp[i])
{
absMax = 2;
for (j = 0; j < numTwoLen; j++)
{
numOneUp[j] ^= numTwoUp[j];
numTwoUp[j] ^= numOneUp[j];
numOneUp[j] ^= numTwoUp[j];
}
return ;
}
else if (numOneUp[i] > numTwoUp[i])
{
return ;
}
}
}
return ;
}
//加减处理
void addOrSub(int numOneLen, int numTwoLen, int flag) //flag加法为1减法为0
{
int i, key = 0, tag, numLenMax, numLenMin;
numOneLen = numOneLen - 1;
numTwoLen = numTwoLen - 1;
//数据逆序
for (i = numOneLen; i > 0; i--)
{
numOneUp[key++] = numOne[i];
}
if (numOne[0] != '-')
{
numOneUp[key] = numOne[0];
numOneLen++;
}
key = 0;
for (i = numTwoLen; i > 0; i--)
{
numTwoUp[key++] = numTwo[i];
}
if (numTwo[0] != '-')
{
numTwoUp[key] = numTwo[0];
numTwoLen++;
}
numLenMax = numOneLen > numTwoLen ? numOneLen : numTwoLen;
numLenMin = numOneLen < numTwoLen ? numOneLen : numTwoLen;
//逐位相加
if (flag)
{
size(numOneLen, numTwoLen);
for (i = 0; i < numLenMax; i++)
{
product[i] = (int)numOneUp[i] - 48;
}
for (i = 0; i < numLenMin; i++)
{
tag = (int)numTwoUp[i]-48;
Carrying(tag, i, product); //递归
}
}
//逐位相减
else
{
size(numOneLen, numTwoLen);
for (i = 0; i < numLenMax; i++)
{
product[i] = (int)numOneUp[i] - 48;
}
for (i = 0; i < numLenMin; i++)
{
tag = -((int)numTwoUp[i]-48);
Abdicate(tag, i, product); //递归
}
}
}
//输出结果
void print()
{
int i, j;
//倒序输出结果
for (i = _MAX - 1; i > 0; i--)
{
if (product[i] != 0)
{
break; //查找到第一个不等于0的跳出
}
}
for (j = i; j >= 0; j--)
{
printf("%d",product[j]);
}
printf("\n");
}
int main(int argc, const char * argv[])
{
int numOneLen, numTwoLen;
scanf("%s %s",numOne,numTwo); //存数据
numOneLen=(int)strlen(numOne);
numTwoLen=(int)strlen(numTwo);
if (numOne[0] == '-' && numTwo[0] == '-')
{
addOrSub(numOneLen, numTwoLen, 1);
printf("-");
print();
}
else if (numOne[0] == '-' || numTwo[0] == '-')
{
addOrSub(numOneLen, numTwoLen, 0);
if ((numOne[0] == '-' && absMax == 1) || (numTwo[0] == '-' && absMax == 2))
{
printf("-");
}
print();
}
else
{
addOrSub(numOneLen, numTwoLen, 1);
print();
}
return 0;
}
也就这样吧,这道题锻炼的是个人的编程基本功底和粗心程度!有点意思-_-#OVER!!!