0

如果我有两个字符串:

a = "1234"
b = "4321"

我可以像这样将两个数字相加:

for(i=0; i<width-1; i++){
    sum = (a[width-2-i]-48) + (b[width-2-i]-48) + carry;
    carry = 0;
    if(sum > 9){
        carry = 1;
        sum-=10;
    }
    answer[i] = sum+48;
}

if(carry) answer[i++] = carry+48;
answer[i]= 0;

然后反转它(宽度等于strlen(a))。

如果出现以下情况,我怎么能做同样的事情?

a = "12345"
b = "4321"

我需要重新分配内存吗?或者是什么?

(顺便说一句 -我要解决的问题是使用许多数字都是 50 位数字,所以我理解 strtoul 或 strtoull 是不可能的。这是我的代码到目前为止。)

4

5 回答 5

1

如果您坚持使用“小学加法”,请找到两个字符串的长度,前进到它们的末端,然后向后移动,直到较短的字符串的长度用完。然后继续只移动较长的字符串,假设较短的字符串的剩余数字为零:

12345
04321

您需要一直移动到较长字符串的开头,并在那里处理进位。请注意,无论如何您都需要分配一个新结果,因为添加两位N数字可能会由于进位而导致一个N+1数字数字。

于 2013-05-21T01:27:52.337 回答
1
int getcharval(const char *s, int idx) {
    if (idx < strlen(s))
        return s[strlen(s) - idx - 1] - 48; 
    return 0;
}

void add() {
    const char *a = "1234";
    const char *b = "13210";
    char answer[256];
    int i, wa=strlen(a), wb=strlen(b), width, sum, carry;
    width = wa > wb ? wa : wb; 
    for(i=0; i<width; i++){
        char ca = getcharval(a, i); 
        char cb = getcharval(b, i); 
        printf("%d %d\n", ca, cb);
        sum = ca + cb + carry;
        carry = 0;
        if(sum > 9){ 
            carry = 1;
            sum-=10;
        }
        answer[i] = sum+48;
    }   
    if(carry) answer[i++] = carry+48;
    answer[i]= 0;
    for (i = 0; i < strlen(answer) / 2; i++) {
        char t = answer[i];
        answer[i] = answer[strlen(answer) - i - 1]; 
        answer[strlen(answer) - i - 1] = t;
    }   

    printf("%s\n", answer);
}
于 2013-05-21T01:33:39.990 回答
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define c2d(c) (c-'0')
#define d2c(c) (c+'0')

char* add(const char *a, const char *b, char *ans){
    int alen, blen;
    int i, carry=0;
    char *wk;
    char *awk=strdup(a);
    char *bwk=strdup(b);

    alen=strlen(strrev(awk));
    blen=strlen(strrev(bwk));
    if(alen<blen){
        alen ^= blen;blen ^= alen;alen ^= blen;//swap
        wk = awk ; awk = bwk ; bwk = wk;
    }
    ans[alen+1]=ans[alen]='\0';
    for(i=0;i<alen;++i){
        int sum = c2d(awk[i])+(i<blen ? c2d(bwk[i]): 0)+carry;
        ans[i] = d2c(sum % 10);
        carry = sum / 10;
    }
    if(carry){
        ans[i++]='1';
    }
    free(awk);
    free(bwk);
    return strrev(ans);
}

int main(){
    const char *a="12345";
    const char *b="4321";
    char ans[6];

    printf("{%s}+{%s}={%s}\n", a, b, add(a,b, ans));
    return 0;
}
于 2013-05-21T09:33:26.407 回答
0

引用自C - 将 2 个字符串中的数字相加,如果答案长度不同 ,我编写了更易读的代码:</p>

void str_reverse(char *beg, char *end){
    if(!beg || !end)return;
    char cTmp;
    while(beg < end){
        cTmp = *beg;
        *beg++ = *end;
        *end-- = cTmp;
    }
}

#define c2d(c) (c - '0')
#define d2c(d) (d + '0')
void str_add(const char* s1, const char* s2, char* s_ret){
    int s1_len = strlen(s1);
    int s2_len = strlen(s2);

    int max_len = s1_len;
    int min_len = s2_len;
    const char *ps_max = s1;
    const char *ps_min = s2;

    if(s2_len > s1_len){
        ps_min = s1;min_len = s1_len;
        ps_max = s2;max_len = s2_len;
    }

    int carry = 0;
    int i, j = 0;
    for (i = max_len - 1; i >= 0; --i) {
        // this wrong-prone
        int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
        int sum = c2d(ps_max[i]) + (idx >=0  ? c2d(ps_min[idx]) : 0) + carry;

        carry = sum / 10;
        sum = sum % 10;

        s_ret[j++] = d2c(sum);
    }

    if(carry)s_ret[j] = '1';
    str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
}

测试代码如下:

void test_str_str_add(){
    char s1[] = "123";
    char s2[] = "456";
    char s3[10] = {'\0'};

    str_add(s1, s2, s3);
    std::cout<<s3<<std::endl;

    char s4[] = "456789";
    char s5[10] = {'\0'};
    str_add(s1, s4, s5);
    std::cout<<s5<<std::endl;

    char s7[] = "99999";
    char s8[] = "21";
    char s9[10] = {'\0'};
    str_add(s7, s8, s9);
    std::cout<<s9<<std::endl;
}

输出:

579

456912

100020

于 2017-12-02T09:13:20.690 回答
0
int num(char x,int len){
    if(len <0)
        return 0;
    return ((x=='1') ? 1 :  (x=='2') ? 2 : (x=='3') ? 3 : (x=='4') ? 4 : (x=='5') ? 5 : (x=='6') ? 6 : (x=='7') ? 7 : (x=='8') ? 8 : 9);
}

int main(){


    int result[100];
    int i=0;
    char num1[] = "123456789123456789";
    char num2[] = "1234567811111111111111111111";
    int carry = 0;
    int l1= strlen(num1)-1;
    int l2 = strlen(num2)-1;
    int result1;


    while(1){
        if(l1 < 0  && l2 <0 && carry == 0)
            break;
        result1 = num(num1[l1],l1) + num(num2[l2],l2);
        l1--;
        l2--;
        if(carry>0){
            result1 +=carry;
            carry = 0;
        }
        carry = result1 / 10;
        result[i] = (result1 % 10);
        i++;
    }

    i--;
    printf("\n");

    while(i>=0){
            printf("%d",result[i]);
            i--;
    }

}
于 2020-05-28T15:21:54.757 回答