51Nod-1005-大數加法
阿新 • • 發佈:2019-01-23
今天遇見一道細節問題特別多的題,寫得我眼疼,題本身不難,難得是他的細節問題繁多,需要考慮的情況也甚多,稍有不慎就側漏了,哈哈。
題的思路也很清晰,就是將最後的結果的正負的符號分離出來,剩下的就是高精度的加減法了,利用字串處理即可,效率可以很高很高,有多高呢?自己感覺吧!
題:
給出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!!!