HDU 1753 大明A+B(大數相加)(string::npos)
話說,經過了漫長的一個多月,小明已經成長了許多,所以他改了一個名字叫“大明”。
這時他已經不是那個只會做100以內加法的那個“小明”了,現在他甚至會任意長度的正小數的加法。
現在,給你兩個正的小數A和B,你的任務是代表大明計算出A+B的值。
Input
本題目包含多組測試資料,請處理到檔案結束。
每一組測試資料在一行裡面包含兩個長度不大於400的正小數A和B。
Output
請在一行裡面輸出輸出A+B的值,請輸出最簡形式。詳細要求請見Sample Output。
Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1
Sample Output
4
3.4555434454
2.1
題意:小明啊你以為你換個馬甲我就不認識你了嘛!!!
解題思路:
哎呀好氣啊。。。
有三種情況:
整數+整數
整數+小數(小數+整數)
小數加小數
處理資料之前判斷一下這個數是整數還是小數,分情況處理。
第一個數存在a[]字串數組裡,
第二個數存在b[]字串數組裡。
第一個數的整數部分存在c[]陣列,長度為p
第一個數的小數部分存在d[]陣列,長度為q
第二個數的整數部分存在e[]陣列,長度為r
第二個數的小數部分存在f[]陣列,長度為s
(為了方便的解讀程式碼= =)
相加後結果的整數部分存在m[]陣列
相加後結果的小數部分存在n[]陣列
下面開始模擬:
資料處理:輸入一個數,將他分為整數部分和小數部分,如果沒有小數部分(即aa.find(“.”)==-1,這個一會要著重說一下= =),則小數部分長度設為1,小數部分就一個數0。
計算:分為整數部分計算和小數部分計算。先進行小數部分計算,方便這種情況:如果有小數部分進位到整數部分則整數部分的個位數+1就行了。
按位計算,n[i]=d[i]+f[i],m[i]=c[i]+e[i]。最重要的就是進位處理了,還有最高一位的情況(在這裡我是單獨輸出最高一位的)。
輸出:按順序輸出,先輸出整數部分,再輸出小數部分。輸出小數部分之前先判斷一下是否存在小數部分(如果小數部分全為0那就是不存在了)。如果存在還有一種特殊情況,如:12.3458+6.7002=19.0460。最後一個0當然是多餘的,怎麼處理呢?在這裡是先把小數部分n[]陣列倒過來判斷一下,如果末位有多餘的0則小數部分的長度就隨之減少,這樣輸出的時候輸到0之前就結束了。詳見程式碼。
這裡說一下string容器。
我是想方便找小數點的,可是發現判斷找不到的返回值跟書上說的有些出入。
原文如下:
採用find()方法可查詢字串中的第一個字元元素(char,用單引號界定)或者子串(用雙引號界定),如果查到,則返回下標值(從0開始計數),如果查不到,則返回4294967295。————曾宗根《ACM程式設計P31》
這個返回值有些特殊,見下:
unsigned int(無符號基本整型) 位元組數4 取值範圍為0~4294967295(即0~2^32-1)
unsigned long long(無符號雙長整型) 位元組數8 取值範圍0~18446744073709551615(即0~2^64-1)
我分別在同一個編譯器上做了兩個實驗,第一個是在數字中查詢小數點的位置,結果找不到都是返回-1,第二是照著書上打的,找不到結果卻返回了第二個值18446744073709551615,但是這三個值都是無符號型。(具體-1怎樣當做無符號型的不再多說)
萬般苦惱。
但終找出兩個解決方案:
1,可以像我一樣提前做個小實驗讀取這個值。。
2,將找不到結果的返回值寫string::npos
!!!
即if(a.find(“xxx”)==string::npos) printf(“沒找著!”\n);
但是對於這道題其實for迴圈就可以了。。
真的不想再多做一遍。。。
總之,還是自己水平太低了。。。
AC程式碼:
(去註釋去調教過程版)
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
string aa,bb;
char a[410],b[410];
int main()
{
int i,j,p,q,r,s,pos1,pos2,l,h;
int c[410],d[410],e[410],f[410],m[410],n[410];
while(~scanf("%s%s",a,b))
{
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
memset(m,0,sizeof(m));
memset(n,0,sizeof(n));
aa=a;
bb=b;
l=strlen(a);
h=strlen(b);
pos1=aa.find(".");
pos2=bb.find(".");
//處理資料
if(pos1==-1)
{
for(i=l-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
q=1;
d[0]=0;
}
else
{
for(i=pos1-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
for(i=pos1+1,q=0;i<l;i++)
{
d[q++]=a[i]-'0';
}
}
if(pos2==-1)
{
for(i=h-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
s=1;
f[0]=0;
}
else
{
for(i=pos2-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
for(i=pos2+1,s=0;i<h;i++)
{
f[s++]=b[i]-'0';
}
}
//計算
int max1=(p>r)?p:r;
int max2=(q>s)?q:s;
//小數部分
for(i=max2-1;i>=1;i--)
{
n[i]=d[i]+f[i];
if(n[i]>=10) {n[i]-=10;d[i-1]++;}
}
n[0]=d[0]+f[0];
if(n[0]>=10) {n[0]-=10;c[0]++;}
//整數部分
for(i=0;i<max1-1;i++)
{
m[i]=c[i]+e[i];
if(m[i]>=10) {m[i]-=10;c[i+1]++;}
}
m[max1-1]=c[max1-1]+e[max1-1];
//輸出結果
//輸出整數部分
for(i=max1-1;i>=0;i--)
{
printf("%d",m[i]);
}
//判斷有沒有小數部分
int flag=0;
for(i=0;i<max2;i++)
{
if(n[i]!=0) flag=1;//如果小數部分有值
}
//輸出小數部分
if(flag==0) printf("\n");
else
{
printf(".");
for(i=max2-1;i>=0;i--)//處理字尾0!
{
if(n[i]!=0) break;
if(n[i]==0) max2--;
}
for(i=0;i<max2;i++)
{
printf("%d",n[i]);
}
printf("\n");
}
}
return 0;
}
(艱辛的調教過程版。。)
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
string aa,bb;
char a[410],b[410];
int main()
{
int i,j,p,q,r,s,pos1,pos2,l,h;
int c[410],d[410],e[410],f[410],m[410],n[410];
while(~scanf("%s%s",a,b))
{
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
memset(m,0,sizeof(m));
memset(n,0,sizeof(n));
aa=a;
bb=b;
l=strlen(a);
h=strlen(b);
pos1=aa.find(".");
pos2=bb.find(".");
//printf("pos1===%d\npos2===%d\n",pos1,pos2);
//if(s.find("a") == string::npos)string::npos通用處理
//處理資料
if(pos1==-1)
{
for(i=l-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
q=1;
d[0]=0;
}
else
{
for(i=pos1-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
for(i=pos1+1,q=0;i<l;i++)
{
d[q++]=a[i]-'0';
}
}
if(pos2==-1)
{
for(i=h-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
s=1;
f[0]=0;
}
else
{
for(i=pos2-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
for(i=pos2+1,s=0;i<h;i++)
{
f[s++]=b[i]-'0';
}
}
/*
printf("************\n");
for(i=0;i<p;i++)
printf("%d",c[i]);
printf("\n");
for(i=0;i<q;i++)
printf("%d",d[i]);
printf("\n");
for(i=0;i<r;i++)
printf("%d",e[i]);
printf("\n");
for(i=0;i<s;i++)
printf("%d",f[i]);
printf("\n");
printf("************\n");
*/
//計算
int max1=(p>r)?p:r;
int max2=(q>s)?q:s;
/*
printf("max1===%d\nmax2===%d\n",max1,max2);
printf("************\n");
printf("f[2]===%d\n",f[2]);
printf("d[2]+f[2]===%d\n",d[2]+f[2]);
printf("d[1]+f[1]===%d\n",d[1]+f[1]);
printf("d[0]+f[0]===%d\n",d[0]+f[0]);
*/
//小數部分
for(i=max2-1;i>=1;i--)
{
n[i]=d[i]+f[i];
//printf("n[%d]===%d\n",i,n[i]);
if(n[i]>=10) {n[i]-=10;d[i-1]++;}
}
n[0]=d[0]+f[0];
//printf("n[0]===%d\n",n[0]);
if(n[0]>=10) {n[0]-=10;c[0]++;}
/*
printf("************\n");
printf("************\n");
for(i=0;i<max2;i++)
printf("%d",n[i]);
printf("\n");
printf("************\n");
*/
//printf("c[0]===%d\n",c[0]);
//整數部分
for(i=0;i<max1-1;i++)
{
m[i]=c[i]+e[i];
//printf("m[%d]===%d\n",i,m[i]);
if(m[i]>=10) {m[i]-=10;c[i+1]++;}
}
m[max1-1]=c[max1-1]+e[max1-1];
//輸出結果
//輸出整數部分
//if(m[max1])
//printf("c[max1-1]===%d\ne[max1-1]===%d\n",c[max1-1],e[max1-1]);
//printf("m[max1-1]===%d\n",m[max1-1]);
for(i=max1-1;i>=0;i--)
{
printf("%d",m[i]);
}
//判斷有沒有小數部分
int flag=0;
for(i=0;i<max2;i++)
{
if(n[i]!=0) flag=1;//如果小數部分有值
}
//輸出小數部分
if(flag==0) printf("\n");
else
{
printf(".");
for(i=max2-1;i>=0;i--)//處理字尾0!
{
if(n[i]!=0) break;
if(n[i]==0) max2--;
}
for(i=0;i<max2;i++)
{
printf("%d",n[i]);
}
printf("\n");
}
}
return 0;
}