1. 程式人生 > 實用技巧 >高精A+B

高精A+B

提供兩種思路,分別是用字元陣列儲存每一位進行計算(2種程式碼)和用int陣列儲存每一位進行計算(1種程式碼)

常見的做法是用int陣列儲存計算,這種方法比字元陣列可以少考慮幾個麻煩,推薦用int陣列儲存計算

當時看到可以用字串儲存大整數,就一直用字元陣列儲存計算,計算過程中需要進行字元‘n’和數字n的轉換,還要取餘、取模,感覺非常彆扭,後來看到別人用整數陣列儲存計算,恍然大悟,覺得自己好傻~

用字元陣列計算主要有兩個麻煩,

第一個,用ASCII碼進行計算,因為涉及到取餘和取模,就很彆扭,但是仍然可以通過減去'0'模擬數字的計算,最後加上'0'變回ASCII碼

第二個,這個比較頭疼,就是當兩個數a,b的長度不同時,很難把共有位的計算和獨有位的計算統一起來(反正我覺得很難),

針對第二個麻煩,有三種思路,

可以將兩個字元陣列全部初始化為'0',這樣相當於長度為500(下面字元陣列所能儲存的最大長度)的兩個大整數相加,長度相同了,

可以將共有位的計算公式和獨有位的區別開,用if……else……

也可以慢慢想,直到想出一個可以統一兩種情況的公式,

字元陣列的高精加法寫了兩種,

第一種,倒序儲存大整數,並且統一了兩種情況

#include <stdio.h>
#include <string.h>
char a[501], b[501], num1[501], num2[501];

int main()
{
    scanf(
"%s", a); scanf("%s", b); int len1 = strlen(a), len2 = strlen(b); if (len1 >= len2)//將整數倒序儲存,且較長的數用num1[]存放 { for (int i = 0; i < len1; i++) num1[i] = a[len1 - 1 - i]; for (int i = 0; i < len2; i++) num2[i] = b[len2 - 1 - i]; }
else { for (int i = 0; i < len1; i++) num2[i] = a[len1 - 1 - i]; for (int i = 0; i < len2; i++) num1[i] = b[len2 - 1 - i]; } len1 = strlen(num1);//len1代表較長的數的長度,len2代表較短的 len2 = strlen(num2); for (int i = 0; i < len1; i++)//用ASCII碼進行計算,比較麻煩 { num1[i + 1] += (num2[i]-'0' + num1[i]-'0') / 10; num1[i] = (num2[i]-'0' + num1[i]-'0') % 10+'0'; } if (num1[len1] == 1) num1[len1] += '0'; for (int i = strlen(num1) - 1; i >= 0; i--) printf("%d", num1[i]-'0'); return 0; }

第二種,順序儲存大整數,模仿n位全加器進行計算,對於兩數長度不同的情況進行了討論,(這是最早寫的程式碼,看著有點不一樣)

#include <stdio.h>
#include <math.h>
#include <string.h>

#define MAXSIZE 600

int main()
{
    char a[MAXSIZE] = { '\0' };
    char b[MAXSIZE] = { '\0' };
    int flag = 0;
    scanf("%s",a);
    scanf("%s",b);
    int i, j;
    char* big;
    char* small;
    if (strlen(a) < strlen(b))
    {
        big = b;
        small = a;

    }
    else
    {
        big = a;
        small = b;
    }
    i = strlen(big) - 1;
    j = strlen(small) - 1;

    while (j!=-1)
    {
        int tmp = small[j] + big[i] + flag;
        if (tmp > '0' + '9')
        {
            flag = 1;
            tmp = tmp - '9' - 1;
        }
        else
        {
            tmp = tmp - '0';
            flag = 0;
        }
        big[i] = tmp;
        i--;
        j--;
    }
    while (i != -1)
    {
        int tmp = flag + big[i];
        if (tmp > '9')
        {
            flag = 1;
            tmp = tmp - 10;
        }
        else
        {
            flag = 0;
        }
        big[i] = tmp;
        i--;
    }
    if(flag)
        printf("1%s", big);
    else
        printf("%s", big);
    return 0;
}

利用整數陣列儲存大整數進行計算,

整體原理和字元陣列的第一種相同,也是最常見的

#include <stdio.h>
#include <string.h>
char a[502], b[502];
int num1[502], num2[502];//元素值預設為0,這個在後面的計算很重要,將兩個大整數統一成長度為501的數,如果用區域性變數,還需要初始化為0才有這樣的效果

int main()
{
    scanf("%s", a);
    scanf("%s", b);

    int len1 = strlen(a), len2 = strlen(b),len=0;

    for (int i = 0; i < len1; i++)
        num1[i] = a[len1 - 1 - i] - '0';
    for (int i = 0; i < len2; i++)
        num2[i] = b[len2 - 1 - i] - '0';
    len = (len1 >= len2) ? len1 : len2;
    for (int i = 0; i < len; i++)
    {
        num1[i + 1] += (num2[i] + num1[i]) / 10;
        num1[i] = (num2[i] + num1[i])% 10;
    }
    if (num1[len] == 1)
        len++;
    for (int i = len - 1; i >= 0; i--)
        printf("%d", num1[i]);

    return 0;
}