题目链接:http://wikioi.com/problem/3115/
http://wikioi.com/problem/3116/
http://wikioi.com/problem/3117/
http://wikioi.com/problem/3118/
算法与思路:大数的加,减,乘算法比较简单,模拟列竖式的计算过程就好;
除法模拟实现比较困难,采用减法的形式实现,例如对于大数a / b,如果a < b,
则直接输出商为0,否则,将a的最后strlen(b)位重复减去b,直到得数小于b,
将执行减法的次数赋给商的个位,然后将b的最后添上一个0,相当于乘以10;
继续执行上述步骤,到a-b <= 0为止,详见代码.
代码实现:
1)大数加法
#include<stdio.h>
#include<string.h>
#define Max 505
int main()
{
char a[Max], b[Max];
int n[Max] = {0}, m[Max] = {0}, s[Max] = {0};
int len_a, len_b, len_max;
scanf("%s%s", a, b);
len_a = strlen(a);
len_b = strlen(b);
for(int i = 0; i < len_a; i++)
n[i] = a[len_a - 1 - i] - '0';
for(int i = 0; i < len_b; i++)
m[i] = b[len_b - 1 - i] - '0';
len_max = len_a > len_b ? len_a : len_b;
int carry = 0;
for(int i = 0; i < len_max; i++)
{
s[i] = (n[i] + m[i] + carry) % 10;
carry = (n[i] + m[i] + carry) / 10;
}
if(carry != 0)
printf("1");
for(int i = len_max - 1; i >=0; i--)
printf("%d", s[i]);
printf("\n");
return 0;
}
2)大数减法
#include <stdio.h>
#include <string.h>
#define Max 505
int flag = 1;
int len_a, len_b;
void sub(int x[], int y[])
{
int i, len;
if(flag == 0)
{
printf("-");
len = len_b;
}
else
len = len_a;
for(i = 0; i < len; i++)
{
x[i] -= y[i];
if(x[i] < 0)
{
x[i] += 10;
x[i + 1]--;
}
}
i = len - 1;
while(x[i] == 0)
i--;
for(;i >= 0; i--)
printf("%d", x[i]);
}
int main()
{
char A[Max], B[Max];
int a[Max] = {0}, b[Max] = {0};
scanf("%s %s", A, B);
len_a = strlen(A);
for(int i = 0; i <= len_a - 1; i++)
a[i] = A[len_a - 1 - i] - '0';
len_b = strlen(B);
for(int i = 0; i <= len_b - 1; i++)
b[i] = B[len_b - 1 - i] - '0';
if(len_a < len_b)
{
flag = 0;
sub(b, a);
}
else if(len_a == len_b)
{
flag = 1;
for(int i = 0; i < len_a; i++)
if(A[i] < B[i])
{
flag = 0;
break;
}
if(flag == 0)
sub(b, a);
else
printf("0");
}
else
{
flag = 1;
sub(a, b);
}
return 0;
}
3)大数乘法
#include<stdio.h>
#include<string.h>
#define Max 505
int main()
{
char A[Max], B[Max], temp[Max];
int a[Max] = {0}, b[Max] = {0}, s[Max * 2] = {0};
int len_a, len_b, i, j;
scanf("%s %s", A, B);
if(strlen(A) < strlen(B))
{
strcpy(temp, A);
strcpy(A, B);
strcpy(B, temp);
}
len_a = strlen(A);
len_b = strlen(B);
for(i = 0; i < len_a; i++)
a[i] = A[len_a - i - 1] - '0';
for(i = 0; i < len_b; i++)
b[i] = B[len_b - i - 1] - '0';
for(i = 0; i < len_b; i++)
for(j = 0; j < len_a; j++)
s[i + j] += a[j] * b[i];
for(i = 0; i < 2 * len_a; i++)
if(s[i] >= 10)
{
s[i + 1] += s[i] / 10;
s[i] %= 10;
}
i = 2 * len_a;
while(s[i] == 0)
i--;
if(i < 0)
printf("0");
else
{
for(;i>= 0; i--)
printf("%d",s[i]);
}
return 0;
}
4)大数除法
#include<stdio.h>
#include<string.h>
#define Max 505
char A[Max], B[Max];
int s[Max] = {0}, len_a, len_b;
void sub()
{
int i, j;
for(i = 0; A[i] == '0'; i++);
j = i;
for(; i < len_b; i++)
A[i] -= B[i] - '0';
for(i = len_b - 1; i > j; i--)
if(A[i] < '0')
{
A[i] += 10;
A[i - 1]--;
}
}
int main()
{
int i, j, k;
scanf("%s %s", A, B);
len_a = strlen(A);
len_b = strlen(B);
if(len_a < len_b || len_a == len_b && strncmp(A, B, len_b) < 0)
printf("0");
else
{
i = 0;
while(1)
{
while(strncmp(A, B, len_b) >= 0)
{
sub();
s[i]++;
}
i++; //商的位数,0是个位,1是十位,以此类推
if(len_a == len_b)
break;
for(j = len_b - 1; j >= 0; j--)
B[j + 1] = B[j];
B[0] = '0';
len_b++;
B[len_b] == '\0';//将减数最后添一个0,相当于乘以10
}
k = 0;
while(1)
{
if(s[k] == 0)
k++;
else
break;
}
for(; k < i; k++)
printf("%d", s[k]);
}
return 0;
}