nyoj A+B Problem IV
A+B Problem IV
時間限制:1000?ms ?|? 內(nèi)存限制:65535?KB 難度:3 描述每組數(shù)據(jù)包含兩個正數(shù)A,B(可能為小數(shù)且位數(shù)不大于400)
測試數(shù)據(jù)都對,又在網(wǎng)上找了別人說的有坑的側(cè)試數(shù)據(jù),也對,就是提交不上
有興趣的看下,,歡迎知道原因的指導
一:
#include <iostream>
using namespace std;
bool flag;//標記是否小數(shù)部分向整數(shù)部分有進位
//計算整數(shù)部分的加法
string add_Int(string s1,string s2)
{
if(s1.length()<s2.length())
{
string t=s1;
s1=s2;
s2=t;
}
for(int i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
if(s1[i]-'0'>=10)
{
s1[i]=char((s1[i]-'0')%10+'0');
if(i)
s1[i-1]++;
else
s1="1"+s1;
}
}
return s1;
}
//計算小數(shù)部分的加法
string add_Dec(string s1,string s2)
{
//如果小數(shù)的位數(shù)不相同
if(s1.length()!=s2.length())
{
if(s1.length()<s2.length())
{
string t=s1;
s1=s2;
s2=t;
}
for(int i=s2.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
if(s1[i]-'0'>=10)
{
s1[i]=char((s1[i]-'0')%10+'0');
if(i)
s1[i-1]++;
else
flag=true;
}
}
}
//小數(shù)部分位數(shù)同
if(s1.length()==s2.length())
{
for(int i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
if(s1[i]-'0'>=10)
{
s1[i]=char((s1[i]-'0')%10+'0');
if(i)
s1[i-1]++;
else
flag=true;
}
bool flag1=true;
for(int i=s1.length()-1;i>=0;--i)
if(s1[i]!='0')
{
flag1=false;
break;
}
if(flag1)
{
s1.clear();
s1+="0";
}
}
}
return s1;
}
int main()
{
string s1,s2;
while(cin>>s1>>s2)
{
string s1_Int,s1_Dec,s2_Int,s2_Dec;
//s1的整數(shù)部分,s1的小數(shù)部分 ,s2的整數(shù)部分,s2的小數(shù)部分
int s1_find=s1.find('.');//找到小數(shù)點的位置,把整數(shù)和小數(shù)分開來計算
if(s1_find!=-1)//如果存在小數(shù)點
{
for(int i=0;i<s1.find('.');++i)
s1_Int+=s1[i];
for(int i=s1.find('.')+1;i<s1.length();++i)
s1_Dec+=s1[i];
}
if(s1_find==-1)//如果不存在小數(shù)點
{
s1_Int+=s1;
s1_Dec+="0";
}
? ? int s2_find=s2.find('.');//s2的小數(shù)點的位置
if(s2_find!=-1)//如果存在小數(shù)點
{
for(int i=0;i<s2.find('.');++i)
s2_Int+=s2[i];
for(int i=s2.find('.')+1;i<s2.length();++i)
s2_Dec+=s2[i];
}
if(s2_find==-1)//如果不存在小數(shù)點
{
s2_Int+=s2;
s2_Dec+="0";
}
flag=false;//默認為false如果有小數(shù)部分進位,則值為true
string t_Dec=add_Dec(s1_Dec,s2_Dec);//先做小數(shù)部分的加法
string t_Int_Carry;//小數(shù)加法時向正數(shù)有進位
string t_Int;//小數(shù)加法向正數(shù)沒有進位
if(flag)// 如果小數(shù)部分向整數(shù)部分有進位
t_Int_Carry=add_Int(add_Int(s1_Int,s2_Int),"1");
else//小數(shù)部分向整數(shù)部分沒有進位
t_Int=add_Int(s1_Int,s2_Int);
if(t_Dec=="0")//如果小數(shù)部分為零
if(flag)//小數(shù)部通過向整數(shù)部分進位 產(chǎn)生的0
cout<<t_Int_Carry<<endl;
else//兩個數(shù)本來都為整數(shù)
cout<<t_Int<<endl;
else//小數(shù)部分不為零
{
if(flag)
cout<<t_Int_Carry<<"."<<t_Dec<<endl;
else
cout<<t_Int<<"."<<t_Dec<<endl;
}
}
return 0;
}
?
二:
#include <iostream>
#include <string>
using namespace std;
string align(string ,int ,int );
int main()
{
int i,j,k;
string a,b;
while(cin>>a>>b)
{
for(j=0;j<a.length() && a[j]!='.';j++);
k=a.length() -j;
for(i=0;i<b.length() && b[i]!='.';i++);
if(i>j)
j=i;
if(b.length() -i>k)
k=b.length() -i; //分別得到整數(shù)最大位數(shù)j和小數(shù)最大位數(shù)k
a=align(a,j,k);
b=align(b,j,k); //按位對齊
for(i=a.length ()-1,j=0;i>=0;i--)
{
if(a[i]!='.')
{//加法運算
a[i]=a[i]+b[i]+j-'0';
j=0;
if(a[i]>'9')
{
j=1;
a[i]-=10;
}
}
}
if(j)
a='1'+a; //補進位
for(i=0;a[i]=='0';i++); //消前導0
for(b="",j=a.length ()-1;a[j]=='0';j--); //消尾數(shù)0
if(a[j]=='.')
j--; //整數(shù)處理
for(;i<=j;i++)
b+=a[i];
cout<<b<<endl;
}
return 0;
}
string align(string s,int ni,int nf)
{//數(shù)據(jù)位對齊
int i,j,k;
for(j=0;j<s.length()&&s[j]!='.';j++);
if(j==s.length())
s+=".0";
k=s.length()-j;
for(i=0;i<ni-j;i++)
s='0'+s;
for(i=0;i<nf-k;i++)
s+='0';
return s;
}
?
?
?
下面附上在網(wǎng)上看的別人的代碼。。。
?
#include<stdio.h>
#include<string.h>
char s1[410],s2[410];
int a1[820],b1[820];
char result[820];
void create(char *s,int *a)
{
int len=strlen(s);
int k;
if(strchr(s,'.')!=NULL) //判斷有無小數(shù)點
k=strchr(s,'.')-s; //標記小數(shù)點的位置
else
k=len; // 無小數(shù)點
for(int i=k+1,j=399;i<len;i++,j--)//小數(shù)點后面的存到前四百位
a[j]=s[i]-'0';
for(int i=k-1,j=400;i>=0;i--,j++)//小數(shù)點前面的存放到后四百位
a[j]=s[i]-'0';
}
void init()
{
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(result,0,sizeof(result));
}
void sum()
{
int s,v=0;
for(int i=0;i<820;i++)
{
s=a1[i]+b1[i]+v;
result[i]=s%10;
v=s/10;
}
}
void print()
{
int i=820;
while(result[i]==0&&i>=400)
{
i--;
}
int j=0;
while(result[j]==0&&j<400)
{
j++;
}
if(i==399&&j==400)//全是零的情況
printf("0\n");
else
{
for(;i>=400;i--)
{
printf("%d",result[i]);
}
if(j!=400)
{
printf(".");
}
for(int i=399;i>=j;i--)
printf("%d",result[i]);
printf("\n");
}
}
int main()
{
while(~scanf("%s %s",s1,s2))
{
init(); //每計算一次初始化數(shù)組
create(s1,a1);//轉(zhuǎn)化過程(2倍數(shù)組倒序存放小數(shù)或整數(shù))
create(s2,b1);//轉(zhuǎn)化過程
sum();//進位求和過程
print();
}
return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/tianzeng/p/9080156.html
總結(jié)
以上是生活随笔為你收集整理的nyoj A+B Problem IV的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [机器学习]梯度提升决策树--GBDT
- 下一篇: Vue是如何渲染页面的,渲染过程以及原理