長整數加法運算/大數運算

長整數加法運算/大數運算

問題描述:
假設2個任意長度的整數x、y分別由雙向鏈表A和B存儲,現要求設計一個算法,實現x+y。計算結果存儲在鏈表C中。

說明:
由於A和B輸出時需要從頭至尾遍歷,而做加法時需要從尾至頭遍歷,因此使用雙向鏈表存儲。
可以從長整數的低位開始拆分(4位爲一組,即不超過9999的非負整數),依次存放在鏈表的每個結點的數據域中;頭結點的數據域存放正負數標誌(正數或0:1,負數:-1)。

輸入說明:
第一行:長整數x
第二行:長整數y

輸出說明:
第一行:格式化後的長整數x(從低位到高位每4位用",“分開)
第二行:格式化後的長整數y(從低位到高位每4位用”,“分開)
第三行:空行
第四行:單鏈表C的遍歷結果
第五行:格式化後的計算結果(從低位到高位每4位用”,"分開)
(輸入與輸出之間用一空行分隔)

輸入:
-53456467576846547658679870988098
435643754856985679

輸出:
-5345,6467,5768,4654,7658,6798,7098,8098
43,5643,7548,5698,5679

5345->6467->5768->4611->2014->9250->1400->2419
-5345,6467,5768,4611,2014,9250,1400,2419

模擬題需要一個具體的步驟,使得思路清晰

  1. 首先是將所給的字符串轉化爲鏈表,這個步驟相對較爲簡單,每四位一取就可以了。
  2. 構建好每個鏈表後就可以進行運算了,這個時候就要考慮兩個數做的是加法還是減法運算。若進行加法運算,就直接進行,這裏所用到的思想類似於歸併排序。做加法運算時,進位位要注意最後結果如果比原鏈表長,則需要再添加。(例如 9999+1=10000)
  3. 做減法的時候,首先要進行比較絕對值的大小,通常運算都是大數減去小數,運算的時候較爲方便。同樣對借位位的考慮需要仔細。
  4. 最後就是輸出,輸出的時候需要考慮中間有的數據爲0,需要補0輸出。首部爲0,則不輸出等。

AC代碼:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
using namespace std;

struct num
{
    int data;
    num *next, *pre;
};

num *creatNum(string s)
{
    num *head=new num;
    num *p=head;
    if(s[0]=='-')
        head->data=-1;
    else
        head->data=1;
    //cout<<head->data<<endl;
    if(head->data==-1){
        int count=(s.length()-1)%4;
        //cout<<count<<endl;
        if(count==0){
            count=3;
            int number=0;
            for(int i=1; i<s.length(); i++){
                number=number*10+s[i]-'0';
                if(count==0){
                    num* temp=new num;
                    temp->data=number;
                    temp->pre=p;
                    p->next=temp;
                    p=p->next;
                    count=4;
                    number=0;
                }
                count--;
            }
        }
        else{
            count--;
            int number=0;
            for(int i=1; i<s.length(); i++){
                number=number*10+s[i]-'0';
                if(count==0){
                    num* temp=new num;
                    temp->data=number;
                    temp->pre=p;
                    p->next=temp;
                    p=p->next;
                    count=4;
                    number=0;
                }
                count--;
            }
        }
    }
    else{
        int count=s.length()%4;
        if(count==0){
            count=3;
            int number=0;
            for(int i=0; i<s.length(); i++){
                number=number*10+s[i]-'0';
                if(count==0){
                    num* temp=new num;
                    temp->data=number;
                    temp->pre=p;
                    p->next=temp;
                    p=p->next;
                    count=4;
                    number=0;
                }
                count--;
            }
        }
        else{
            count--;
            int number=0;
            for(int i=0; i<s.length(); i++){
                number=number*10+s[i]-'0';
                if(count==0){
                    num* temp=new num;
                    temp->data=number;
                    temp->pre=p;
                    p->next=temp;
                    p=p->next;
                    count=4;
                    number=0;
                }
                count--;
            }
        }
    }
    p->next=head;
    head->pre=p;
    return head;
}

void display(num* head)
{
    num* p = head->next;
    while (p!=head && p->data == 0)p = p->next;
    if (p==head) { cout << 0 << endl; return; }
    if (p!=head)
    {
        cout << p->data;
        p = p->next;
    }
    while (p!=head)
    {
        cout << "->";
        cout << setw(4) << setfill('0') << p->data;
        p = p->next;
    }
    cout << endl;
}
void my_print(num* head)
{
    num* p = head->next;
    while (p!=head && p->data == 0)p = p->next;
    if (p==head) { cout << 0 << endl; return; }
    if (head->data == -1)cout << "-";
    if (p!=head)
    {
        cout << p->data;
        p = p->next;
    }
    while (p!=head)
    {
        cout << ",";
        cout << setw(4) << setfill('0') << p->data;
        p = p->next;
    }
    cout << endl;
}

num *add(num* A, num *B)
{
    num *head=new num;
    head->data=A->data;
    head->next=head;
    head->pre=head;
    num *pa=A->pre, *pb=B->pre;
    int carry=0;
    while(pa!=A&&pb!=B){
        num *temp=new num;
        temp->data=(pa->data+pb->data+carry)%10000;
        carry=(pa->data+pb->data+carry)/10000;
        pa=pa->pre;
        pb=pb->pre;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    while(pa!=A){
        num *temp=new num;
        temp->data=(pa->data+carry)%10000;
        carry=(pa->data+carry)/10000;
        pa=pa->pre;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    while(pb!=B){
        num *temp=new num;
        temp->data=(pb->data+carry)%10000;
        carry=(pb->data+carry)/10000;
        pb=pb->pre;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    if(carry==1){
        num *temp=new num;
        temp->data=1;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    return head;
}

int judge(string s1, string s2)
{
    if(s1[0]=='-'){
        if(s1.length()-1>s2.length())
            return 1;
        else if(s1.length()-1<s2.length())
            return -1;
        else{
            bool flag=false;
            for(int i=0; i<s2.length(); i++){
                if(s1[i+1]>s2[i])
                    return 1;
                else if(s1[i+1]<s2[i])
                    return -1;
            }
            if(flag)
                return 0;
        }
    }
    else{
        if(s1.length()>s2.length()-1)
            return 1;
        else if(s1.length()<s2.length()-1)
            return -1;
        else{
            bool flag=false;
            for(int i=0; i<s1.length(); i++){
                if(s1[i]>s2[i+1])
                    return 1;
                else if(s1[i]<s2[i+1])
                    return -1;
            }
            if(flag)
                return 0;
        }
    }
}

num *sub(num *A, num *B)
{
    num *head=new num;
    head->data=A->data;
    head->next=head;
    head->pre=head;
    num *pa=A->pre, *pb=B->pre;
    int carry=0;
    while(pa!=A&&pb!=B){
        num *temp=new num;
        if(pa->data-carry<pb->data){
            temp->data=(10000+pa->data-carry-pb->data)%10000;
            carry=1;
        }
        else{
            temp->data=(pa->data-carry-pb->data)%10000;
            carry=0;
        }
        pa=pa->pre;
        pb=pb->pre;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    while(pa!=A){
        num *temp=new num;
        if(pa->data-carry<0){
            temp->data=(10000+pa->data-carry)%10000;
            carry=1;
        }
        else{
            temp->data=(pa->data-carry)%10000;
            carry=0;
        }
        pa=pa->pre;
        temp->next=head->next;
        temp->pre=head;
        head->next->pre=temp;
        head->next=temp;
    }
    return head;
}


int main()
{
    string s1, s2;
    cin>>s1>>s2;
    num *A=creatNum(s1);
    num *B=creatNum(s2);
    //cout<<A->next->data;
    my_print(A);
    my_print(B);
    cout<<endl;

    //判斷加減運算
    num *res=NULL;
    if(A->data==B->data){
        res=add(A, B);
    }
    else{
        int flag=judge(s1, s2);
        if(flag==0){
            res=sub(A, B);
            res->data=0;
        }
        else if(flag==1)
            res=sub(A, B);
        else
            res=sub(B, A);
    }
    display(res);
    my_print(res);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章