7.A+B(2)

Description

【感谢魏枻舟等同学对本题提出的修改建议】

龙龙觉得之前的二进制加法可能对你来说太简单了,正好你也学完了“字符串处理”专题,那么就来考验一下你对大数加法的熟练程度吧?下面举一个实数加法运算的实例:

   2.01
+  1.0
-------
   3.01

请你模拟这个过程。

Input

第一行输入一个实数 a表示加数,第二行输入一个实数b 表示被加数,保证输入实数的长度 <1000,而且 a 和b 非负,可能会有前导零和后导零出现。

Output

请模拟实数加法,按题目描述的格式输出。注意换行,程序输出中没有多余的空格和换行。

Hint
  • 前后导零:对于一个实数数的非零部分假设为 a1a2…an.b1b2…bm其中a 为整数部分并且 n>0,点为小数点,b为小数部分,其等价的前导0 实数 00…0a1a2…an.b1b2…bm,如0001.23 ,但是请注意 0.23  的零不是前导零,也等价于后导 0实数a1a2…an.b1b2…bm ,如1.23=1.23000 。
  • 输出格式:每行输出的字符个数相同,包括横杠字符-所在行。每行空格与加号也计入该行字符个数中,也就是说可能有前缀空格,也可能有后缀空格。输出的实数如果有小数点,则按小数点对齐,其余部分用空格补满。若加数与被加数小数部分精度不同,则运算结果请按精度更高的小数位输出,精度不足部分请补0 。输出部分的两个加数与输入一致(即保留前导0),运算结果的整数部分不保留前导0
测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 2.01↵
  2. 1.0↵
以文本方式显示
  1.    2.01↵
  2. +  1.0 ↵
  3. -------↵
  4.    3.01↵
1秒64M0
测试用例 2以文本方式显示
  1. 1.0↵
  2. 9.0↵
以文本方式显示
  1.     1.0↵
  2. +   9.0↵
  3. -------↵
  4.    10.0↵
1秒64M0
测试用例 3以文本方式显示
  1. 009.9999↵
  2. 00.0001↵
以文本方式显示
  1.    009.9999↵
  2. +   00.0001↵
  3. -----------↵
  4.     10.0000↵
1秒64M0
测试用例 4以文本方式显示
  1. 00.0↵
  2. 0.00↵
以文本方式显示
  1.    00.0 ↵
  2. +   0.00↵
  3. --------↵
  4.     0.00↵
1秒64M0
测试用例 7以文本方式显示
  1. 1740948824551711527614232216857618927954312334113874277931986502860248650900613893446066184963788291359840763615420973726016575412001460717777335998182660380125094783512016406189841439880877838371073.4965109968348499255333743808806819897228289078158612425862653924618211976295200391819532525867722941969825549125083939679976935766582544161633553282536186214629150364929344059634288758125744444293077↵
  2. 8730382520372975343211325351222640703400531067500454956482168314849207060705673849265774579830223671554026061117300483012903885770893074783710083450145620356667677191627276513995926532444279237315785.8324115951064530891347463652810315522174823630352807225910850790534104859254139582796177190341753324129087456807743136301904293148205593287481435526892959450588013222703133709558378379391828018486093↵
以文本方式显示
  1.     1740948824551711527614232216857618927954312334113874277931986502860248650900613893446066184963788291359840763615420973726016575412001460717777335998182660380125094783512016406189841439880877838371073.4965109968348499255333743808806819897228289078158612425862653924618211976295200391819532525867722941969825549125083939679976935766582544161633553282536186214629150364929344059634288758125744444293077↵
  2. +   8730382520372975343211325351222640703400531067500454956482168314849207060705673849265774579830223671554026061117300483012903885770893074783710083450145620356667677191627276513995926532444279237315785.8324115951064530891347463652810315522174823630352807225910850790534104859254139582796177190341753324129087456807743136301904293148205593287481435526892959450588013222703133709558378379391828018486093↵
  3. ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------↵
1秒64M0
思路

先说一点。本题“-”数量比上题多一,宽度为最长数+3。大体思路和上题基本一样。

先用strchr寻找小数点,没有的话就记为末尾后一位。然后前后补零。我使用了memset和strcat函数,将字符串前后和零连起来。我直接补的是空格,方便输出,计算的时候按0算。自己调试时可以先用‘*’,更直观清晰。最后再替换就行。

注意输入可能会有前导零。所以结果要检查前导零。但注意若结果为零,不能把零全抹了,以及0.x,小数点前一位0;

虽然说题目说长度<1k,但我字符串开到3000都不行,索性开了10000.

代码
#include<stdio.h>
#include<string.h>
#define N 10000
char a[N]={0},b[N]={0},t1[N]={0},t2[N]={0},t[N]={0},c[N]={0};

main()
{	
	int la,lb,l1,l2,l,i,j,k,pa,pb,flag=0,m,n;
	/* 输入*/
	gets(a);
	gets(b);
	la=strlen(a);
	lb=strlen(b);
		
	/*寻找小数点,如果整数末尾补点*/
	pa=strchr(a,'.')-a;
	pb=strchr(b,'.')-b;
	if(pa<0) pa=la;
	if(pb<0) pb=lb;
	
	/*前导0*/
	if(pa>pb){
		memset(t2,' ',pa-pb);
		strcat(t2,b);
		strcpy(t1,a);
		l1=la;
		l2=strlen(t2);
	}
	else if(pa<pb){
		memset(t2,' ',pb-pa);
		strcat(t2,a);
		strcpy(t2,b);
		l1=strlen(t1);
		l2=lb;
	}
	else{
		strcpy(t1,a);
		strcpy(t2,b);
		l1=la;
		l2=lb;
	}
	
	/*后导0*/
	if(l1>l2){
		memset(t,' ',l1-l2);
		strcat(t2,t);
	}
	else if(l1<l2){
		memset(t,' ',l2-l1);
		strcat(t1,t);		
	}
	//printf("%s\n%s",t1,t2);
	l=strlen(t1);
	
	/*计算*/
	i=l-1;
	j=0;
	while(i>=0){
		if(t1[i]=='.'){
			c[j++]='.';
			i--;
			continue;
		}
		
		if(t1[i]==' ')	m=0;
		else	m=t1[i]-'0';
		if(t2[i]==' ')	n=0;
		else	n=t2[i]-'0';
		
		if(flag+m+n>=10) {
			c[j++]=flag+m+n-10+'0';
			flag=1;
		}
		else {
			c[j++]=flag+m+n+'0';
			flag=0;			
		}
		i--;
	}
	if(flag==1)	{
		c[j++]='1';
		k=4;
	}
	else k=3;
	
	/*输出*/
	if(k==4)	printf("    ");
	else 	printf("   ");
	for(i=0;i<l;i++){
		printf("%c",t1[i]);
	}
	printf("\n");	
	
	if(k==4)	printf("+   ");
	else 	printf("+  ");
	for(i=0;i<l;i++){
		printf("%c",t2[i]);
	}
	printf("\n");
	
	for(i=0;i<j+3;i++)	printf("-");
	printf("\n");
	
	printf("   ");
	i=j-1;/*删除前导0*/
	while(c[i]=='0'){
		if(i==0&&c[i]=='0'||c[i-1]=='.'){
			printf("0");
			i--;
			break;
		}	
		printf(" ");
		i--;
	}
	
	for(;i>=0;i--){
		printf("%c",c[i]);
	}
	printf("\n");
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北辰2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值