【大风】Add与高精度加法两题的代码分享:atoi和sprint函数

首先是Add题:

实现函数add(char[], char[], char[]), 其中第一个和第二个参数是加法的操作数,第三个参数是这两个参数的和,储存计算的结果。 其中,给定的加法操作数以字符串给出,长度不超过8,均为正整数。main函及数据的读取已经给定,只需include相应头文件,实现函数的定义即可。

注意到数字长度不超过8,即在int范围内,我们可以用atoi函数将字符串转成数字,再用sprintf,把和赋值给ans字符串。

sprintf的用法和printf差不多,只不过是把输出的结果赋值到字符串中。

#include
#include 
#include 
void add(char ope1[], char ope2[], char ans[])
{
    int num1=atoi(ope1),num2=atoi(ope2);
    sprintf(ans,"%d",num1+num2);
}

来看高精度加法的题目:

实现函数:short * plus(short , short )
该函数接受两个short型数组作为参数,表示两个高精度非负整数,并返回他们的和。
两个short型数组均一节表示一位,下标为0的是最高位,如a[0] = 1, a[1] = 0,则该数组表示整数10。
返回的数组应当使用同样的格式.

以下是main函数代码:

#include 
#include 
#include 

#define MAXl (100+1)

int main() {
    short s1[MAXl], s2[MAXl];
    int l1, l2, i;
    scanf("%d", &l1);
    for (i = 0; i < l1; ++i)
        scanf("%hd", s1+i);
    scanf("%d", &l2);
    for (i = 0; i < l2; ++i)
        scanf("%hd", s2+i);
    s1[l1] = s2[l2] = -1;
    short *plus(short *, short *);
    short *ans = plus(s1, s2);
    for (i = 0; s1[i] >= 0; ++i)
        printf("%hd", s1[i]);
    printf("\n");
    for (i = 0; s2[i] >= 0; ++i)
        printf("%hd", s2[i]);
    printf("\n");
    for (i = 0; ans[i] >= 0; ++i)
        printf("%hd", ans[i]);
    printf("\n");
    free(ans);
    return 0;
}

其实由main函数的代码可以看出,高精度数字在数组中是用了-1作为结束的标准。比如我要存高精度数字12345到数组a中,那么a={1,2,3,4,5-1};

弄明白这点后,我们就要像平常笔算加法一样,一位一位地相加。

我的代码是:

 #include 
short *plus (short *a,short *b)
{
    int asize=0,bsize=0;
    for (int i=0;*(a+i)>=0;i++) asize++;
    for (int i=0;*(b+i)>=0;i++) bsize++;

    int MAXN=(asize>bsize?asize:bsize);
    short *temp=(short*) malloc((MAXN+10)*sizeof(short));
    short *ans=(short*) malloc((MAXN+10)*sizeof(short));
    short count=0;
    int i=1;
    for (;i<=MAXN;i++)
    {
        short a_digit=asize-i>=0?*(a+asize-i):0;
        short b_digit=bsize-i>=0?*(b+bsize-i):0;

        temp[i]=a_digit+b_digit+count;
        count=temp[i]/10;
        temp[i]%=10;
    }
    if (count>0) temp[++MAXN]=count;

    for (int i=MAXN,j=0;i>=1;i--,j++)
    {
        *(ans+j)=*(temp+i);
    }
    *(ans+MAXN)=-1;
    free(temp);
    return ans; 
}

先找出a和b两个数的位数,从而确定和的位数。
count变量记录进位。

以下是matrix上的标答。

#include 

short *plus(short *a, short *b) {
    int la, lb, n, i;
    for (la = 0; a[la] >= 0; ++la)
        continue;
    for (lb = 0; b[lb] >= 0; ++lb)
        continue;
    if (la < lb)
        n = lb;
    else
        n = la;
    short *ans = (short*)malloc(sizeof(a[0])*(n+2));
    for (i = 0; i < n; ++i)
        if (i < la && i < lb)
            ans[i] = a[la-i-1]+b[lb-i-1];
        else if (i < la)
            ans[i] = a[la-i-1];
        else
            ans[i] = b[lb-i-1];
    for (i = 0; i < n-1; ++i)
        if (ans[i] > 9) {
            ++ans[i+1];
            ans[i] -= 10;
        }
    if (ans[n-1] > 9) {
        ans[n] = 1;
        ans[n-1] -= 10;
        ans[n+1] = -1;
    } else {
        ans[n] = -1;
        --n;
    }
    for (i = n/2; i >= 0; --i) {
        la = ans[i];
        ans[i] = ans[n-i];
        ans[n-i] = la;
    }
    return ans;
}

P.S.其实第一题也可以用高精度的算法解决。在这里,我只是想为大家介绍下atoi,sprint这两个非常好用的函数。

我们可以在cplusplus.com 搜到这两个函数的具体用法。

事实上,高精度的算法经常以字符串的形式实现。因为字符串处理起来更方便,有很多方便使用的函数(string.h里),可以直接用%s输入输出。

上面我们实现的是十进制的高精度,其他进制的高精度实现也是一样的,只需要把进位那处改一下。

如果给出的数字很大,几千上万位,而程序对运行时间的要求又很高,这时候,像我们刚刚那样一位一位算高精度就可能超时了。这时候,我们可以写个10000进制的高精度算法,就避免了这个问题。

希望大家课后回去尝试下,高精度乘法,高精度减法,高精度除法,高精度开平方如何实现。

你可能感兴趣的:(【大风】Add与高精度加法两题的代码分享:atoi和sprint函数)