A+B Problem IV 大实数加法

原文链接: A+B Problem IV 大实数加法

上一篇: A-B Problem 大数相等

下一篇: 求高精度幂 (未完成)

A+B Problem IV

http://acm.nyist.net/JudgeOnline/problem.php?pid=513

时间限制:1000 ms  |  内存限制:65535 KB

难度:3

输入

包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)

输出

每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。

样例输入

1.9 0.1
0.1 0.9
1.23 2.1
3 4.0

样例输出

2
1
3.33
7

描述

acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。

我的代码

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

#define MAX 1000
char a[MAX], b[MAX], c[MAX];

//处理化简数字 000.0100  --> 0.01 
void deal(char *s) {
	int len, i, t, k, dot;

	//  .1 --> 0.1
	if (s[0] == '.') {
		len = strlen(s);
		for (i = len + 1; i > 0; i--)
			s[i] = s[i - 1];
		s[0] = '0';
	}

	//去除整数前导零
	for (i = 0; s[i] && s[i] == '0' && s[i + 1] && s[i + 1] != '.'; i++);
	//左移 i 位 
	if (i > 0) {
		for (k = 0; s[k + i]; k++)
			s[k] = s[k + i];
		s[k] = '\0';
	}

	//去除小数后面的 0 
	for (dot = 0; s[dot] && s[dot] != '.'; dot++);
	len = strlen(s);
	for (i = len - 1; i > dot && s[i] == '0'; i--);
	s[i + 1] = '\0';
	if (s[i] == '.') s[i] = '\0';
}
int main(int argc, char *argv[]) {
	int lena, lenb, lenc, t, d, i, j, k, dota, dotb, dotc;
	while (scanf("%s %s", a, b) != EOF) {
		deal(a);
		deal(b);
//		printf("%s %s\n", a, b);

		//加法
		lena = strlen(a);
		lenb = strlen(b);
		lenc = 0;
		d = 0;		//进位 
		for (dota = 0; a[dota] && a[dota] != '.'; dota++);
		for (dotb = 0; b[dotb] && b[dotb] != '.'; dotb++);
		i = lena - 1;
		j = lenb - 1;
		// i, j 分别指向 a, b 
		while (i >= 0 && j >= 0) {
			if (i > dota && j > dotb) {
				//小数部分 
				if (i - dota == j - dotb) {
					t = a[i--] + b[j--] - 2 * '0' + d;
				} else if (i - dota > j - dotb) {
					t = a[i--] + d - '0';
				} else if (i - dota < j - dotb) {
					t = b[j--] - '0' + d;
				}
				if (t > 9) {
					d = 1;
					c[lenc++] = t % 10 + '0';
				} else {
					d = 0;
					c[lenc++] = t + '0';
				}
			} else if (i < dota && j < dotb) {
				//整数部分 
				if (i - dota == j - dotb) {
					t = a[i--] + b[j--] - 2 * '0' + d;
				} else if (i - dota < j - dotb) {
					t = a[i--] + d - '0';
				} else if (i - dota > j - dotb) {
					t = b[j--] - '0' + d;
				}
				if (t > 9) {
					d = 1;
					c[lenc++] = t % 10 + '0';
				} else {
					d = 0;
					c[lenc++] = t + '0';
				}
			} else if (i == dota && j == dotb) {
				//小数点
				c[lenc++] = '.';
				i--; j--;
			} else if (i == dota && j != dotb) {
				//小数点
				c[lenc++] = '.';
				i--;
			} else if (i != dota && j == dotb) {
				//小数点
				c[lenc++] = '.';
				j--;
			} else if (i > dota && j < dotb) {
				t = a[i--] + d - '0';
				if (t > 9) {
					d = 1;
					c[lenc++] = t % 10 + '0';
				} else {
					d = 0;
					c[lenc++] = t + '0';
				}
			} else if (i<dota && j>dotb) {
				t = b[j--] + d - '0';
				if (t > 9) {
					d = 1;
					c[lenc++] = t % 10 + '0';
				} else {
					d = 0;
					c[lenc++] = t + '0';
				}
			}
		}
		for (; i >= 0; i--) {
			t = a[i] - '0' + d;
			if (t > 9) {
				d = 1;
				c[lenc++] = t % 10 + '0';
			} else {
				d = 0;
				c[lenc++] = t + '0';
			}
		}
		for (; j >= 0; j--) {
			t = b[j] - '0' + d;
			if (t > 9) {
				d = 1;
				c[lenc++] = t % 10 + '0';
			} else {
				d = 0;
				c[lenc++] = t + '0';
			}

		}
		if (d) {
			c[lenc++] = d + '0';
		}
		c[lenc] = '\0';
//		printf("%s\n", c);

		//化简c
		for (dotc = lenc - 1; dotc >= 0 && c[dotc] != '.'; dotc--);		
		for (i = 0; i < dotc && c[i] == '0'; i++);
		if (c[i] == '.') i++;
		for(j=lenc-1;j>0 && c[j]=='0' && c[j+1]!='.' &&c[j+1];j--);
		for (; j >= i; j--)
			printf("%c", c[j]);
		printf("\n");
	}

	return 0;
}

题目推荐

 
 
#include <stdio.h>
#include <string.h>
#define MAX 1000
char a[MAX],b[MAX],c[MAX];
int main()
{
	int i,j,k,l,m,n,la,lb,mx;
	char ch;
	memset(a,'0',sizeof(a));
	memset(b,'0',sizeof(b));
	while(~scanf("%s%s",a,b))
	{
		la=strlen(a);
		lb=strlen(b);
		a[la]='0';
		b[lb]='0';
		i=0;
		while((a[i]-'.')&&i<la)
		{
			i++;
		}
		if(i==la)
			a[la]='.';
		j=0;
		while((b[j]-'.')&&j<lb)
		{
			j++;
		}
		if(j==lb)
			b[lb]='.';
		m=(la-i)>(lb-j)?(la-i):(lb-j);
		if(i>=j)
		{
			for(l=mx=i+m,k=0,j=i-j;l>=0;l--)
			{
				if(a[l]=='.')
				{
					c[l]='.';
					continue;
				}
				ch=(l-j)<0?'0':b[l-j];
				c[l]=(a[l]-'0'+ch-'0'+k)%10+'0';
				k=(a[l]-'0'+ch-'0'+k)/10;
			}
		}
		else
		{
			for(l=mx=j+m,k=0,j=j-i;l>=0;l--)
			{
				if(b[l]=='.')
				{
					c[l]='.';
					continue;
				}
				ch=(l-j)<0?'0':a[l-j];
				c[l]=(ch-'0'+b[l]-'0'+k)%10+'0';
				k=(ch-'0'+b[l]-'0'+k)/10;
			}
		}
		if(k>0)
			printf("%d",k);
		while(c[mx]=='0')
			mx--;
		if(c[mx]=='.')
			mx--;
		for(i=0;i<=mx;i++)
			printf("%c",c[i]);
		printf("\n");
		memset(a,'0',sizeof(a));
		memset(b,'0',sizeof(b));
	}
}                

测试数据

00.000 0000.00000
0
1 9
10
998.900 001.900
1000.8
998.900 001.100
1000

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值