1. 程式人生 > >51Nod-1005-大數加法

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!!!