首先是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进制的高精度算法,就避免了这个问题。
希望大家课后回去尝试下,高精度乘法,高精度减法,高精度除法,高精度开平方如何实现。