九度 题目1003:A+B

来源:互联网 发布:java应届生求职简历 编辑:程序博客网 时间:2024/06/05 02:09

题目

题目描述:

给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号”,”隔开。
现在请计算A+B的结果,并以正常形式输出。

输入:
输入包含多组数据数据,每组数据占一行,由两个整数A和B组成(-10^9 < A,B < 10^9)。

输出:
请计算A+B的结果,并以正常形式输出,每组数据占一行。

样例输入:
-234,567,890 123,456,789
1,234 2,345,678
样例输出:
-111111101
2346912
来源:
2010年浙江大学计算机及软件工程研究生机试真题

分析

该题与2616年3月28日阿里内推笔试第一题很相似, 区别在于阿里那道题要求处理大数, 而且数字之间没有”,”. 下面的分析与解法将考虑存在大数的情况.

  1. 因为输入字符串中存在逗号, 因此先对两个字符串进行预处理. 分配新的数组, 在对原指针数组遍历的过程中将逗号去除, 复制到新的数组.
  2. 如果两个数字符号相同, 则进行加法, 所得结果符号与任一加数符号相同; 如果两个数字符号相反, 则进行减法, 所得结果符号与绝对值较大的加数符号相同.
    1). 对于第一种情况, 从两数字最低位 (字符串最后一位) 开始相加, 依次向前, 注意对进位的处理. 处理完公共长度后, 需要对某一较长的数字的剩余部分进行处理.
    2). 对于第二种情况, 让指针pa指向绝对值较大的数, pb指向绝对值较小的数, 注意字符串长度要与之保持对应. 然后对两者的绝对值进行相减, 所得结果非负, 最终符号由绝对值较大的数字决定.
  3. 对于结果数组中的前导0需要跳过.

解答

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdbool.h>#define MAX_LEN 3000void do_calc(char *a, char *b){    int nega, negb, neg=0;    nega = (a[0] == '-' ? 1 : 0);    negb = (b[0] == '-' ? 1 : 0);    char *pa = ((*a == '+' || *a == '-') ? (a+1) : (a));    char *pb = ((*b == '+' || *b == '-') ? (b+1) : (b));    // the length of the number part    int lena = strlen(pa);    int lenb = strlen(pb);    char result[MAX_LEN];    memset(result, 0, sizeof(char) *(MAX_LEN));    int k = 0;    if ((nega && negb) || (!nega && !negb)) {        int carry = 0;        // both neg. or pos. do addition, the sign is the same        // as either operand        if (nega && negb){            neg = 1; // both are neg. so the result is also neg.        }        int i = lena - 1;        int j = lenb - 1;        while (i >= 0 && j >= 0) {            int tmp = (pa[i--]-'0') + (pb[j--]-'0') + carry;            int digit = tmp % 10;            carry = tmp / 10;            result[k++] = digit+'0';        }        // if either operand has some digits left        while (i >= 0) {            int tmp = pa[i--] - '0' + carry;            int digit = tmp % 10;            carry = tmp / 10;            result[k++] = digit +'0';        }        while (j >= 0) {            int tmp = pb[j--] - '0' + carry;            int digit = tmp % 10;            carry = tmp / 10;            result[k++] = digit +'0';        }        if (carry > 0) {            result[k++] = carry + '0';        }    } else {        // different sign, do minus        int borrowed = 0;        if (lena < lenb || (lena == lenb && strcmp(pa, pb) == -1)) {            // make pa point to the one with bigger abs. value            char *ctmp = pa;            pa = pb; pb = ctmp;            int lentmp = lena;            lena = lenb; lenb = lentmp;            // conceptually negativity should also be swaped, but we can            // just assign negb to neg and omit the negativity swap            neg = negb;        } else {            neg = nega;        }        int i = lena-1;        int j = lenb-1;        while (i >=0 && j>=0) {            int tmp = (pa[i--] - '0') - (pb[j--] - '0');            if (borrowed) {                tmp -= 1;            }            if (tmp < 0) {                tmp += 10;                borrowed = 1;            } else {                borrowed = 0;            }            result[k++] = tmp % 10 + '0';        }        // pa points the larger number, so only one while        while (i >= 0) {            int tmp = pa[i--] - '0';            if (borrowed) {                tmp -= 1;            }            if (tmp < 0) {                tmp += 10;                borrowed = 1;            } else {                borrowed = 0;            }            result[k++] = tmp % 10 + '0';        }    }    // k points to one element past the last element, so we go back    k--;    while (k > 0 && result[k] == '0')        k--; // skip leading zeros    if (k == 0 && result[k] == '0') {        printf("0\n"); // the result is zero, print and exit        return ;    }    if (neg) {        printf("-");    }    while (k >= 0) {        printf("%c", result[k]);        k--;    }    printf("\n");}void add_number(char *a, char *b){    char a2[MAX_LEN];    char b2[MAX_LEN];    char *pa = a, *pa2 = a2;    char *pb = b, *pb2 = b2;    // preprocess to remove ","    while (*pa) {        if (*pa != ',') {            *pa2++ = *pa;        }        pa++;    }    *pa2 = '\0';    while (*pb) {        if (*pb != ',') {            *pb2++ = *pb;        }        pb++;    }    *pb2 = '\0';    do_calc(a2, b2);}int main(){    char a[MAX_LEN];    char b[MAX_LEN];    while (scanf("%s %s", a, b) != EOF) {        add_number(a, b);    }}
0 0
原创粉丝点击