SLIDE1

Thursday, May 14, 2015

cộng trừ nhân chia số nguyên lớn không giới hạn

viết chương trình định nghĩa kiểu số nguyên lớn không giới hạn, lập trình thực hiện các phép toán công (+) trừ (-) nhân (*) chia (/) các số nguyên lớn đó. thông thường ta thấy các kiểu float, int có giới hạn của nó, khi vượt quá giớ hạn thì báo lỗi hoặc cho kết quả sai, sau khi học qua danh sách liên kết thì t có thực hiện bài tập giải quyết số nguyên lớn không giới hạn, định nghĩa và thiết kế thuật toán công trừ nhân chia các số nguyên lớn đó. dưới đây là code của chương trình đó, tuy nhiên t không viết chú thích nên có phần khó. dã học qua danh sách liên kết và năm rõ về nó thì sẽ dễ đọc code hơn. mỗi node trong danh sách sẽ lưu 1 chữ só của số nguyên lớn, 1 biến kiểu char trong danh sách để lưu dấu ccủa số là dương hay âm. giá trị của mỗi node trong danh sách theo thứ tự từ đầu đến cuối là giá trị các chữ số của số nguyên lớn. do đó khi công trừ nhân chia, ta duyệt từng node trong danh sách là tiến hành tính toán trên đó, cộng trừ nhân thì thực hiện từ cuối lên đầu, còn chia thì thực hiện duyệt từ đầu đến cuối
#include<iostream>
#include<string>
#include<Windows.h>
using namespace std;
typedef struct tagnode
{
    int x;
    struct tagnode *next;
    struct tagnode *pre;
}node;
typedef struct tagsolon
{
    char c;
    node *dau;
    node *cuoi;
}solon;
void xuat(solon n);
void taosolon(solon &n);
node *taonode(int x);
void themdau(solon &n,node *p);
void nhap(solon &n);
void cong(solon n1,solon n2,solon &n);
void tru(solon n1,solon n2,solon &n);
int sosanh(solon n1,solon n2);
void nhan(solon n1,solon n2,solon &n);
void nhan1so(solon n1,int x,solon &n);
void themcuoi(solon &n,node *p);
void xoa(solon &n);
void xoatruocQ(solon &n,node *Q);
void xoacuoi(solon &n);
void chia(solon n1,solon n2,solon &n);
void xuly(solon &n);

void main()
{
    solon n,n1,n2;
    taosolon(n);taosolon(n1);taosolon(n2);
    cout<<"nhap 2 so nguyen:\n";
    cout<<"a=";nhap(n1);
    cout<<"b=";nhap(n2);
    cout<<"\n1.cong."
        <<"\n2.tru."
        <<"\n3.nhan."
        <<"\n4.chia.\n\n";
    int k;
    cin>>k;
    switch(k)
    {
    case 1:cong(n1,n2,n);cout<<"a+b = ";xuat(n);cout<<endl;break;
    case 2:tru(n1,n2,n);cout<<"a-b = ";xuat(n);cout<<endl;break;
    case 3:nhan(n1,n2,n);cout<<"a*b = ";xuat(n);cout<<endl;break;
    case 4:chia(n1,n2,n);break;
    }
    system("pause");
}


void chia(solon n1,solon n2,solon &n)
{
    if(n1.c==n2.c) n.c='+';
    else n.c='-';
    int q=sosanh(n1,n2);
    if(q<0)
    {
        cout<<"ket qua = 0 \ndu ";xuat(n1);
    }
    else if(q==0) cout<<"ket qua = 1";
    else
    {
        int i;
        solon a;taosolon(a);
        solon b;taosolon(b);
        solon c;taosolon(c);
        node *p,*p2,*p1;
        p1=n1.dau;
        p2=n2.dau;
        while(p2!=NULL)
        {
            p=taonode(p1->x);
            themcuoi(a,p);
            p1=p1->next;
            p2=p2->next;
        }
        while(p1!=NULL)
        {
            q=sosanh(a,n2);
            if(q<0)
            {
                p=taonode(0);
                themcuoi(n,p);
                p=taonode(p1->x);
                themcuoi(a,p);
            }
            else if(q==0)
            {
                p=taonode(1);
                themcuoi(n,p);
                xoa(a);
                p=taonode(p1->x);
                themcuoi(a,p);
            }
            else
            {
                for(i=1;i<=9;i++)
                {
                    xoa(b);
                    nhan1so(n2,i,b);
                    q=sosanh(a,b);
                    if(q<0)
                    {
                        xoa(b);
                        nhan1so(n2,i-1,b);
                        break;
                    }
                }
                i--;
                p=taonode(i);
                themcuoi(n,p);
                xoa(c);
                tru(a,b,c);
                xoa(a);
                p2=c.dau;
                while(p2!=NULL)
                {
                    p=taonode(p2->x);
                    themcuoi(a,p);
                    p2=p2->next;
                }
                p=taonode(p1->x);
                themcuoi(a,p);
            }
            if(p1!=NULL)p1=p1->next;
        }
        // thuc hien 1 lan nua
        q=sosanh(a,n2);
        if(q<0)
        {
            p=taonode(0);
            themcuoi(n,p);
        }
        else if(q==0)
        {
            p=taonode(1);
            themcuoi(n,p);
        }
        else
        {
            for(i=1;i<=9;i++)
            {
                xoa(b);
                nhan1so(n2,i,b);
                q=sosanh(a,b);
                if(q<0)
                {
                    xoa(b);
                    nhan1so(n2,i-1,b);
                    break;
                }
            }
            i--;
            p=taonode(i);
            themcuoi(n,p);
            xoa(c);
            tru(a,b,c);
            xoa(a);
            p2=c.dau;
            while(p2!=NULL)
            {
                p=taonode(p2->x);
                themcuoi(a,p);
                p2=p2->next;
            }
        }
        if(p1!=NULL)p1=p1->next;
        //end
        xuly(n);xuly(a);
        cout<<"a/b = ";xuat(n);cout<<endl;
        if(a.dau!=NULL)
        {
            cout<<"du ";
            xuat(a);
            cout<<endl;
        }
    }
}
void xoatruocQ(solon &n,node *Q)
{
    if(Q==NULL) xoacuoi(n);
    else
    {
        node *p=Q->pre;
        if(p!=NULL)
        {
            if(p==n.dau)
            {
                n.dau=Q;
                n.dau->pre=NULL;
                delete p;
            }
            else
            {
                p->pre->next=Q;
                Q->pre=p->pre;
                delete p;
            }
        }
    }
}
void xuly(solon &n)
{
    node *p=n.dau;
    while(p!=NULL && p->x==0)
    {
        p=p->next;
        xoatruocQ(n,p);
    }
}
void nhan(solon n1,solon n2,solon &n)
{
    node *p,*p1,*p2;
    long long i,dem=0;
    solon a;taosolon(a);
    solon b;taosolon(b);
    p=n2.cuoi;
    while(p!=NULL)
    {
        xoa(a);
        nhan1so(n1,p->x,a);
        for(i=0;i<dem;i++)
        {
            p1=taonode(0);
            themcuoi(a,p1);
        }
        xoa(b);
        p2=n.cuoi;
        while(p2!=NULL)
        {
            p1=taonode(p2->x);
            themdau(b,p1);
            p2=p2->pre;
        }
        xoa(n);
        cong(a,b,n);
        p=p->pre;
        dem++;
    }
    if(n1.c==n2.c) n.c='+';
    else n.c='-';
    xuly(n);
}
void xoa(solon &n)
{
    while(n.dau!=NULL) xoacuoi(n);
}
void xoacuoi(solon &n)
{
    node *p=n.cuoi;
    if(p!=NULL)
    {
        if(n.dau==n.cuoi)
        {
            n.dau=n.cuoi=NULL;
            delete p;
        }
        else
        {
            n.cuoi=p->pre;
            n.cuoi->next=NULL;
            delete p;
        }
    }
}
void themcuoi(solon &n,node *p)
{
    if(n.dau==NULL)n.dau=n.cuoi=p;
    else
    {
        n.cuoi->next=p;
        p->pre=n.cuoi;
        n.cuoi=p;
    }
}
void nhan1so(solon n1,int x,solon &n)
{
    node *p1,*p;
    int k,m=0;
    p1=n1.cuoi;
    while(p1!=NULL)
    {
        k=p1->x*x+m;
        if(k>=10)
        {
            m=k/10;
            k=k%10;
        }
        else m=0;
        p=taonode(k);
        themdau(n,p);
        p1=p1->pre;
    }
    if(m>0)
    {
        p=taonode(m);
        themdau(n,p);
    }
}
void tru(solon n1,solon n2,solon &n)
{
    int q=sosanh(n1,n2);
    int k,m;
    node *p,*p1,*p2;
    if(q==0) return;
    if(n1.c=='+' && n2.c=='+')
    {
        if(q>0)
        {
            m=0;n.c='+';
            p1=n1.cuoi;p2=n2.cuoi;
            while(p1!=NULL && p2!=NULL)
            {
                if(p1->x < (p2->x + m))
                {
                    k=10+p1->x-p2->x-m;
                    m=1;
                }
                else
                {
                    k=p1->x-p2->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p1=p1->pre;
                p2=p2->pre;
            }
            while(p1!=NULL)
            {
                if(p1->x < m)
                {
                    k=10+p1->x-m;
                    m=1;
                }
                else
                {
                    k=p1->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p1=p1->pre;
            }
        }
        else
        {
            m=0;n.c='-';
            p1=n1.cuoi;p2=n2.cuoi;
            while(p1!=NULL && p2!=NULL)
            {
                if(p2->x < (p1->x + m))
                {
                    k=10+p2->x-p1->x-m;
                    m=1;
                }
                else
                {
                    k=p2->x-p1->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p2=p2->pre;
                p1=p1->pre;
            }
            while(p2!=NULL)
            {
                if(p2->x < m)
                {
                    k=10+p2->x-m;
                    m=1;
                }
                else
                {
                    k=p2->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p2=p2->pre;
            }
        }
    }
    else if(n1.c=='-' && n2.c=='-')
    {
        if(q>0)
        {
            m=0;n.c='-';
            p1=n1.cuoi;p2=n2.cuoi;
            while(p1!=NULL && p2!=NULL)
            {
                if(p1->x < (p2->x + m))
                {
                    k=10+p1->x-p2->x-m;
                    m=1;
                }
                else
                {
                    k=p1->x-p2->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p1=p1->pre;
                p2=p2->pre;
            }
            while(p1!=NULL)
            {
                if(p1->x < m)
                {
                    k=10+p1->x-m;
                    m=1;
                }
                else
                {
                    k=p1->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p1=p1->pre;
            }
        }
        else
        {
            m=0;n.c='+';
            p1=n1.cuoi;p2=n2.cuoi;
            while(p1!=NULL && p2!=NULL)
            {
                if(p2->x < (p1->x + m))
                {
                    k=10+p2->x-p1->x-m;
                    m=1;
                }
                else
                {
                    k=p2->x-p1->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p2=p2->pre;
                p1=p1->pre;
            }
            while(p2!=NULL)
            {
                if(p2->x < m)
                {
                    k=10+p2->x-m;
                    m=1;
                }
                else
                {
                    k=p2->x-m;
                    m=0;
                }
                p=taonode(k);
                themdau(n,p);
                p2=p2->pre;
            }
        }
    }
    else if(n1.c=='+' && n2.c=='-')
    {
        n2.c='+';
        cong(n1,n2,n);
    }
    else if(n1.c=='-' && n2.c=='+')
    {
        n2.c='-';
        cong(n1,n2,n);
    }
    xuly(n);
}
void cong(solon n1,solon n2,solon &n)
{
    if(n1.c==n2.c)
    {
        n.c=n1.c;
        int k,m=0;
        node *p1=n1.cuoi,*p2=n2.cuoi,*p;
        while(p1!=NULL && p2!=NULL)
        {
            k=p1->x+p2->x+m;
            if(k>=10)
            {
                m=k/10;
                k=k%10;
            }
            else m=0;
            p=taonode(k);
            themdau(n,p);
            p1=p1->pre;
            p2=p2->pre;
        }
        while(p1!=NULL)
        {
            k=p1->x+m;
            if(k>=10)
            {
                m=k/10;
                k=k%10;
            }
            else m=0;
            p=taonode(k);
            themdau(n,p);
            p1=p1->pre;
        }
        while(p1!=NULL)
        {
            k=p1->x+m;
            if(k>=10)
            {
                m=k/10;
                k=k%10;
            }
            else m=0;
            p=taonode(k);
            themdau(n,p);
            p1=p1->pre;
        }
        if(m>0)
        {
            p=taonode(m);
            themdau(n,p);
        }

    }
    else if(n1.c=='+' && n2.c=='-')
    {
        n2.c='+';
        tru(n1,n2,n);
    }
    else
    {
        n1.c='+';
        tru(n2,n1,n);
    }
    xuly(n);
}
int sosanh(solon n1,solon n2)
{
    node *p1=n1.cuoi,*p2=n2.cuoi;
    while(p1!=NULL && p2!=NULL)
    {
        p1=p1->pre;
        p2=p2->pre;
    }
    if(p1==NULL && p2!=NULL) return -1;
    if(p1!=NULL && p2==NULL) return 1;
    if(p1==NULL && p2==NULL)
    {
        p1=n1.dau;
        p2=n2.dau;
        while(p1!=NULL && p2!=NULL)
        {
            if(p1->x > p2->x) return 1;
            if(p1->x < p2->x) return -1;
            p1=p1->next;
            p2=p2->next;
        }
        return 0;
    }
}
void xuat(solon n)
{
    node *p=n.dau;
    if(p==NULL)
    {
        cout<<0;
        return;
    }
    if(p!=NULL && n.c=='-') cout<<n.c;
    while(p!=NULL)
    {
        cout<<p->x;
        p=p->next;
    }
}
void taosolon(solon &n)
{
    n.c='+';
    n.dau=n.cuoi=NULL;
}
node *taonode(int x)
{
    node *p=new node;
    if(p==NULL) exit(1);
    p->x=x;
    p->next=p->pre=NULL;
    return p;
}
void themdau(solon &n,node *p)
{
    if(n.dau==NULL) n.dau=n.cuoi=p;
    else
    {
        p->next=n.dau;
        n.dau->pre=p;
        n.dau=p;
    }
}
void nhap(solon &n)
{
    string s;
    node *p;
    long long i,j=0;
    getline(cin,s);
    if(s[0]=='-')
    {
        n.c='-';
        j=1;
    }
    else if(s[0]=='+')
    {
        n.c='+';
        j=1;
    }
    else n.c='+';
    for(i=s.size()-1;i>=j;i--)
    {
        switch(s[i])
        {
        case '0':p=taonode(0);break;
        case '1':p=taonode(1);break;
        case '2':p=taonode(2);break;
        case '3':p=taonode(3);break;
        case '4':p=taonode(4);break;
        case '5':p=taonode(5);break;
        case '6':p=taonode(6);break;
        case '7':p=taonode(7);break;
        case '8':p=taonode(8);break;
        case '9':p=taonode(9);break;
        }
        themdau(n,p);
    }
}
trên đây là toàn bộ code của chương trình cộng trừ nhân chia số nguyên lớn không giới hạn. code hơi dài, t mất 10 tiếng đồng hồ để suy nghĩ cách làm và cài đặt code, pro đọc qua thấy hay thì like và cải tiến code hoặc gởi form liên hệ code hay hơn để t học hỏi nhé!

Related Posts:

  • thuật toán heap sort - sắp xếp vun đống, (cây) thuật toán heap sort - sắp xếp vun đống, (cây) Heap Sort tận dụng được các phép so sánh ở bước i-1 mà thuật toán sắp xếp chọn trực tiếp không tận dụng được Để làm được điều này Heap sort thao tác dựa trên cây. Ở cây trê… Read More
  • thuật toán quick sort - sắp xếp nhanh Giải thuật QuickSort sắp xếp dãy a1, a2 ..., aN dựa trên việc phân hoạch dãy ban đầu thành 3 phần : Phần 1: Gồm các phần tử  có giá trị bé hơn x Phần 2: Gồm các phần tử  có giá trị bằng  x Phần 3: Gồm các phần… Read More
  • thuật toán merge sort - sắp xếp trộn Giải thuật Merge sort sắp xếp dãy a1, a2, ..., an dựa trên nhận xét sau: Mỗi dãy a1, a2, ..., an bất kỳ là một tập hợp các dãy con liên tiếp mà mỗi dãy con đều đã có thứ tự. Ví dụ: dãy 12, 2, 8, 5, 1, 6, 4, 15 có thể coi… Read More
  • danh sách liên kết đơnMỗi phần tử liên kết với phần tử đứng liền sau trong danh sách Mỗi phần tử trong danh sách liên kết đơn là một cấu trúc có hai thành phần Thành phần dữ liệu: Lưu trữ thông tin về bản thân phần tử Thành phần liên kết: Lưu địa … Read More
  • thuật toán sắp xếp radix sort Radix Sort là một thuật toán tiếp cận theo một hướng hoàn toàn khác. Nếu như trong các thuật toán khác, cơ sở để sắp xếp luôn là việc so sánh giá trị của 2 phần tử thì Radix Sort lại dựa trên nguyên tắc phân loại thư của b… Read More