北理工H 高精度加减法*
H 高精度加减法*(选做)
背景:
计算机所能完成的一个基本功能就是完成数据的计算,譬如加法、减法等等。但是在任何一种计算机上,计算中能够使用的数字都是有一定范围的,超过了范围,就没法得到精确的结果。
你现在接受了一个任务,要编写一个高精度计算器的核心部分。所谓高精度计算器,就是可以计算很大很大的数据的计算器。
输入:
输入的第一行是一个正整数,表示下面有几组数据需要计算。之后的每一行是两个十进制的正整数和一个运算符,每个整数可以由最多 500 个数字组成。运算符可以是加号或者减号。
输出:
对应着输入的每一行数据,输出计算的结果,每个结果占一行。
| 测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
|---|---|---|---|---|---|
| 测试用例 1 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
| 测试用例 2 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
| 测试用例 3 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
思路如下:
思路
#include<stdio.h>
#include<math.h>
#include <ctype.h>
#include <stdbool.h>
void input(char a[], int* len_a, char* sign, char b[], int* len_b);
void char_to_int(char a[], int len_a, int x[], char b[], int len_b, int y[]);
int max(int a, int b);
void minus(int huge[], int small[], int c[], int len, char sign);
int main()
{
/*char a[505],b[505],读入符号+,-。用switch
* 首先把字符转成对应数字,并且为了方便起见,数字倒序,存入x,y[505]
* int c[505]来存储最终结果
* switch(ch){
* case '+' :
* c[i] += x[i] + y[i];
* c[i+1] += c[i]/10;
* c[i] %= 10;
*
* case '-' :
* 转为大数减小数,先判断位数,再比较最高位
* if(x[i] < y[i]){
* x[i+1]--;
* x[i] += 10;
}
* c[i] = x[i] - y[i]; *
* default :
* }
* 最后逆序打印
*/
int n;
scanf("%d ", &n);
for (; n>0; n--) {
char a[505] = { 0 }, b[505] = { 0 };
int len_a = 0,len_b = 0;
char sign = 0;
int x[505] = { 0 }, y[505] = { 0 };
int c[505] = { 0 };
input(a, &len_a, &sign, b, &len_b);
char_to_int(a, len_a, x, b, len_b, y);
int i = 0;
switch (sign) {
case '+' :
for (i = 0; i <=max(len_a,len_b); i++) {
c[i] += x[i] + y[i];
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
//printf("i = %d\n", i);
if (c[i] == 0) {
//printf("I'm 0\n");
for (--i; i >= 0; i--)
printf("%d", c[i]);
putchar('\n');
}
else {
//printf("I'm not 0\n");
for (; i >= 0; i--)
printf("%d", c[i]);
putchar('\n');
}
break;
case '-' :
if (len_a < len_b) {
minus(y, x,c,len_b,'-');
}
else if (len_a > len_b) {
minus(x, y,c,len_a,'+');
}
else {
for (i = 0; i <= len_a; i++) {
if (a[i] == b[i])
continue;
else if (a[i] > b[i]) {
minus(x, y,c,len_a,'+');
break;
}
else {
minus(y, x,c,len_a,'-');
break;
}
}
if (i == len_a + 1) printf("0\n");
}
break;
default:
printf("Error!\n");
break;
}
}
return 0;
}
void input(char a[],int*len_a,char* sign,char b[],int* len_b)
{
char ch = getchar();
int i = 0;
while (isdigit(ch)) {
a[i++] = ch;
ch = getchar();
}
*len_a = i - 1;
//printf("len_a = %d\n", *len_a);
*sign = ch;
i = 0;
ch = getchar();
while (isdigit(ch)) {
b[i++] = ch;
ch = getchar();
}
*len_b = i - 1;
//printf("len_b = %d\n", *len_b);
}
void char_to_int(char a[],int len_a, int x[], char b[],int len_b ,int y[])
{
for (int i = 0; len_a >= 0; len_a--, i++) {
x[i] = a[len_a] - '0';
//printf("%d", x[i]);
}
//putchar('\n');
for (int i = 0; len_b >= 0; len_b--, i++) {
y[i] = b[len_b] - '0';
//printf("%d", y[i]);
}
//putchar('\n');
}
int max(int a, int b)
{
int ret = a;
if (a < b)
ret = b;
return ret;
}
void minus(int huge[],int small[],int c[],int len, char sign)
{
int i = 0;
for (i=0; i <= len;i++) {
if (huge[i] < small[i]) {
huge[i + 1]--;
huge[i] += 10;
}
c[i] = huge[i] - small[i];
}
switch (sign) {
case '+': break;
case '-':putchar('-'); break;
default:printf("Unecpected error!\n"); break;
}
bool flag = true;
for (i = len; i >= 0; i--) {
if (c[i] == 0 && flag) continue;
else {
printf("%d", c[i]);
flag = false;
}
}
putchar('\n');
}
最终版本:
#include<stdio.h>
#include<math.h>
#include <ctype.h>
#include <stdbool.h>
void input(char a[], int* len_a, char* sign, char b[], int* len_b);
void char_to_int(char a[], int len_a, int x[], char b[], int len_b, int y[]);
int max(int a, int b);
void minus(int huge[], int small[], int c[], int len, char sign);
int main()
{
int n;
scanf("%d ", &n);
for (; n>0; n--) {
char a[505] = { 0 }, b[505] = { 0 };
int len_a = 0,len_b = 0;
char sign = 0;
int x[505] = { 0 }, y[505] = { 0 };
int c[505] = { 0 };
input(a, &len_a, &sign, b, &len_b);
char_to_int(a, len_a, x, b, len_b, y);
int i = 0;
switch (sign) {
case '+' :
for (i = 0; i <=max(len_a,len_b); i++) {
c[i] += x[i] + y[i];
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
if (c[i] == 0) {
for (--i; i >= 0; i--)
printf("%d", c[i]);
putchar('\n');
}
else {
for (; i >= 0; i--)
printf("%d", c[i]);
putchar('\n');
}
break;
case '-' :
if (len_a < len_b) {
minus(y, x,c,len_b,'-');
}
else if (len_a > len_b) {
minus(x, y,c,len_a,'+');
}
else {
for (i = 0; i <= len_a; i++) {
if (a[i] == b[i])
continue;
else if (a[i] > b[i]) {
minus(x, y,c,len_a,'+');
break;
}
else {
minus(y, x,c,len_a,'-');
break;
}
}
if (i == len_a + 1) printf("0\n");
}
break;
default:
printf("Error!\n");
break;
}
}
return 0;
}
void input(char a[],int*len_a,char* sign,char b[],int* len_b)
{
char ch = getchar();
int i = 0;
while (isdigit(ch)) {
a[i++] = ch;
ch = getchar();
}
*len_a = i - 1;
*sign = ch;
i = 0;
ch = getchar();
while (isdigit(ch)) {
b[i++] = ch;
ch = getchar();
}
*len_b = i - 1;
}
void char_to_int(char a[],int len_a, int x[], char b[],int len_b ,int y[])
{
for (int i = 0; len_a >= 0; len_a--, i++) {
x[i] = a[len_a] - '0';
}
for (int i = 0; len_b >= 0; len_b--, i++) {
y[i] = b[len_b] - '0';
}
}
int max(int a, int b)
{
int ret = a;
if (a < b)
ret = b;
return ret;
}
void minus(int huge[],int small[],int c[],int len, char sign)
{
int i = 0;
for (i=0; i <= len;i++) {
if (huge[i] < small[i]) {
huge[i + 1]--;
huge[i] += 10;
}
c[i] = huge[i] - small[i];
}
switch (sign) {
case '+': break;
case '-':putchar('-'); break;
default:printf("Unecpected error!\n"); break;
}
bool flag = true;
for (i = len; i >= 0; i--) {
if (c[i] == 0 && flag) continue;
else {
printf("%d", c[i]);
flag = false;
}
}
putchar('\n');
}

浙公网安备 33010602011771号