1. 程式人生 > >HDU 1753 大明A+B(大數相加)(string::npos)

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;
}