zoukankan      html  css  js  c++  java
  • 【数据结构】大数相乘 块链串

    输出两个不超过100位的大整数的乘积。

    【样例输入】

    1234567891011121314151617181920

    2019181716151413121110987654321

    【样例输出】

    2492816912877266687794240983772975935013386905490061131076320

    #include<bits/stdc++.h>
    using namespace std;
    #define Maxsize 1101
    
    int main()
    {
            int intnum1[Maxsize],intnum2[Maxsize];
            int n1=0,n2=0;
            cin>>intnum1>>intnum2;
            int *result=new int[n1+n2];// 分配一个空间,用来存储运算的结果,num1长的数 * num2长的数,结果不会超过num1+num2长
            memset(result,0,sizeof(int)*(n1+n2));
    //        9  8
    //   ×    2  1
    //-------------
    //       (9)(8)  <---- 第1趟: 98×1的每一位结果
    //  (18)(16)     <---- 第2趟: 98×2的每一位结果
    //-------------
    //  (18)(25)(8)  <---- 这里就是相对位的和,还没有累加进位
    //---------------------
            int i=0,j=0;
            for(i=0;i<n1;i++) // 先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上
            {
                for(j=0;j<n2;j++)
                {
                    result[i+j+1]+=intnum1[i]*intnum2[j];//注意在此时+=,9+16在同一下标操作(因为进位的问题,最终放置到第i+j+1位)
                }//空出了result[0]的位置 看嘛i=j=0的时候直接result[1]了
            }
            i--;j--;//!!!一定要记得i--,j--;实际的i和j最后出循环多加了1
            for(int k=i+j+1;k>0;k--)//单独处理进位,从个位处理的数开始,即最后的下标
            {
    
                if(result[k]>=10&&result[k]<100)//进位为10了
                {
                    result[k-1]+=result[k]/10;//注意是+=
                    result[k]%=10;
                }
                
            }
            for(int m=0;m<=i+j+1;m++)
               {
                if(result[0]==0)
                     continue;
                else cout<<result[m];
               }
    
    
    }

    用块链串知识:  块链串: 本质依然是顺序存储,每个字串用数组接纳,各内存块用指针顺序链接

    比如每一个结点存储5位,12345678983426801则需要4个结点;先实现大整数乘上一个一位数;再实现两个大数相加。

    用这样的链式存储形式便于计算:12--->34567--->89834--->26801 或者:26801--->89834--->34567--->12

    来自于组里的大神:

    #include<bits/stdc++.h>
    using namespace std;
    int result[210];
    //块链串
    struct Link
    {
        int maxsize;
        int num[5];
        Link *next;
    };
    
    //初始化块链串
    Link *Init(Link *p,char s[])
    {
        Link *head = p;
        for(int i=0; s[i]!=''; i++)
        {
            if(i!=0&&i%5==0)//用过一轮,数组满了,需要重新分配空间
            {
                p->next = new Link();
                p = p->next;
            }
            p->num[i%5]=s[i]-'0';
            p->maxsize = i%5;
        }
        p->next=NULL;
        return head;
    }
    
    
    //核心算法
    void bigNum(Link *head1,Link *head2)
    {
        Link *p,*q;
        
        //M,N是偏移值
        //M处理第一个串的不同节点之间的相加时的定位
        //N处理另一个串
        int N=0,M=0;
        int i=0,j;
        //max是当前最大长度。
        int max=0;
        
        //乘法部分:
        //从第一个串的头部开始遍历。
        for(p=head1; p!=NULL; p=p->next)
        {
            //如果第一个串一个结点存不下所有的值,那么就涉及到不同结点之间,相加乘积时的定位问题
            if(p!=head1)
                N+=5;
            //遍历第一个串的具体结点
            for(i=0; i<=p->maxsize; i++)
            {
                for(q=head2; q!=NULL; q=q->next)
                {
                    if(q!=head2)
                        M+=5;
                    for(j=0; j<=q->maxsize; j++)
                    {
                        //因为涉及到进位问题,所以+1预留一个进位空间。
                        //M+N+i+j+1即是目前需要相加的偏移量。
                        result[M+N+i+j+1]+=q->num[j]*p->num[i];
                        //cout<<i<<" "<<j<<" "<<i+j+N+M+1<<endl;
                        //得到最大长度,便于确定result结果数组的长度。
                        max=max>M+N+1+j+i?max:M+N+i+j+1;
                    }
                }
                //M和N的区别,M需要重新置为0
                M=0;
            }
        }
        
       /*for(int k=0; k<=max; k++)
            cout<<result[k]<<" ";
        cout<<endl;*/
        
        //处理进位:
        for(int k=max;k>0; k--)
        {
            if(result[k]>=10)
            {
                result[k-1]+=result[k]/10;
                result[k]%=10;
            }
        }
        
        //如果结果没有多一位,第一位则是0,输出时就要跳过
        //如果进位,就直接输出。
        int k=0;
        if(result[k]==0)
            k++;
        for(; k<=max; k++)
            cout<<result[k];
        cout<<endl;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        char s[100],t[100];
        cin>>s>>t;
        Link *head1,*head2,*p;
        p = new Link();
        head1 = Init(p,s);
        p = new Link();
        head2 = Init(p,t);
        bigNum(head1,head2);
        return 0;
    }
    © 2019 GitHub, Inc.
  • 相关阅读:
    很长的下拉框菜单
    Pure CSS Buttons – Good Button Style and No Images
    ssh 配置
    php大量session存储到内存中,散列及过期回收
    array_append_distinct, array_erase函数
    关于C# 中的Attribute 特性(转载)
    Jquery如何操作Table的某一个td
    ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期
    ASP.NET应用程序生命周期趣谈(五) IIS7瞎说
    ASP.NET应用程序生命周期趣谈(三)
  • 原文地址:https://www.cnblogs.com/yundong333/p/10586103.html
Copyright © 2011-2022 走看看