1. 程式人生 > >Openjudge 1.13 33:實數加法

Openjudge 1.13 33:實數加法

33:實數加法
描述
求2個實數相加的和。
輸入輸出中出現的實數都有如下的形式: P1P2...Pi.Q1Q2...Qj。對於整數部分,P1P2...Pi是一個非負整數;對於小數部分,至少有一位且最後一位Qj不等於0。

輸入
2行,分別是兩個加數。每個加數不超過100個字元。
輸出
一行輸出是相應的和。資料保證一定是一個小數部分不為0的實數。

樣例輸入

0.111111111111111111111111111111
0.111111111111111111111111111111
樣例輸出

0.222222222222222222222222222222

題目分析:

本題與其他大整數加法不同,它的加數中含有小數部分,所以在開始運算之前需分離整數和小數。對於整數加法,我們需要從高位至低位倒序儲存,但是對於小數部分,由於是由十分位、百分位、千分位向下排列,所以儲存時直接順向儲存即可。我本題中先運算的是整數部分,但先運算小數部分應該更加簡潔。小數部分需要從最後一位向前加,注意碰到進位時,向前一位進位,但如果小數的十分位需要進位,那麼需要進到整數的個位。整數部分的前導零必須去掉,出現前導零的情況通常是整數部分為0的情況,此時整數部分只輸出一個0,所以我先用一個“for”迴圈判斷整數部分是否為0,再進行輸出。由於題目已經給出小數部分不為0,所以可以直接輸出小數點和小數部分。

程式樣例(僅供參考,非最優):

#include<cstdio>
#include<cstring>
int main()
{
    char a[105],b[105];
    gets(a);
	gets(b);
	int lena=strlen(a),lenb=strlen(b),zsa[105]={},zsb[105]={},xsa[105]={},xsb[105]={};
	int szsa=0,szsb=0,sxsa=0,sxsb=0;
	//分離倒序a
	for(int h=0,oa=1;h<lena;h++)
	{
		if(a[h]=='.')
			oa=0;
		else
			oa? zsa[szsa++]=a[h]-'0':xsa[sxsa++]=a[h]-'0';
	}
	int sy[105]={};
	for(int i=0,j=szsa-1;i<szsa;i++,j--)
		sy[i]=zsa[j];
	for(int i=0;i<szsa;i++)
		zsa[i]=sy[i];
	//分離倒序b
	for(int g=0,ob=1;g<lenb;g++)
	{
		if(b[g]=='.')
			ob=0;
		else
			ob? zsb[szsb++]=b[g]-'0':xsb[sxsb++]=b[g]-'0';
	}
	memset(sy,0,sizeof(sy));
	for(int i=0,j=szsb-1;i<szsb;i++,j--)
		sy[i]=zsb[j];
	for(int i=0;i<szsb;i++)
		zsb[i]=sy[i];
	//整數加法
	int max_zs=szsa>szsb? szsa:szsb,endzs[105]={},sendzs;
	sendzs=max_zs+2;
	for(int i=0;i<max_zs;i++)
	{
		endzs[i]+=zsa[i]+zsb[i];
		if(endzs[i]>=10)
		{
			endzs[i]-=10;
			endzs[i+1]++;
		}
	}
	while(endzs[sendzs]==0 && sendzs>1)
		sendzs--;
	//小數加法
	int max_xs=sxsa>sxsb? sxsa:sxsb,endxs[105]={},sendxs;
	sendxs=max_xs+1;
	for(int i=max_xs-1;i>=0;i--)
	{
		endxs[i]+=xsa[i]+xsb[i];
		if(endxs[i]>=10)
		{
			if(i==0)
			{
				endzs[0]++;
				endxs[0]-=10;
			}
			else
			{
				endxs[i-1]++;
				endxs[i]-=10;
			}
		}
	}
	while(endxs[sendxs]==0 && sendxs>0)
		sendxs--;
	//小數再判進位
	for(int i=sendxs-1;i>=0;i--)
	{
		if(endxs[i]>=10)
		{
			endxs[i]-=10;
			if(i>=1)
				endxs[i-1]++;
			else
				endzs[0]++;
		}
	}
	//整數再判進位,判斷是否為0
	bool zero=true;
	for(int i=0;i<sendzs;i++)
	{
		if(endzs[i]!=0)
			zero=false;
		if(endzs[i]>=10)
		{
			endzs[i+1]++;
			endzs[i]-=10;
		}
	}
	sendzs+=2;
	while(endzs[sendzs]==0 && sendzs>1)
		sendzs--;
	//輸出
	if(zero)
		printf("%d",0);
	else
		for(int i=sendzs;i>=0;i--)
			printf("%d",endzs[i]);
	for(int i=0;i<=sendxs;i++)
	{
		if(i==0)
			printf(".");
		printf("%d",endxs[i]);
	}
    return 0;
}