zoukankan      html  css  js  c++  java
  • 大数问题

     一:大数加法

    1)

    模板:

    string sum(string s1,string s2) 
    { 
      if(s1.length()<s2.length()) 
      { 
        string temp=s1; 
        s1=s2; 
        s2=temp; 
      } 
      int i,j; 
      for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) 
      { 
        s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 
        if(s1[i]-'0'>=10) 
        { 
          s1[i]=char((s1[i]-'0')%10+'0'); 
          if(i) s1[i-1]++; 
          else s1='1'+s1; 
        } 
    } 
      return s1; 
    }

    test:

    #include <iostream> 
    #include <string> 
    #include <cstdio> 
    using namespace std; 
    string sum(string s1,string s2) 
    { 
      f(s1.length()<s2.length()) 
      { 
        string temp=s1; 
        s1=s2; 
        s2=temp; 
      } 
      int i,j; 
      for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--) 
      { 
        s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0)); //注意细节 
        if(s1[i]-'0'>=10) 
        { 
          s1[i]=char((s1[i]-'0')%10+'0'); 
          if(i)
    
            s1[i-1]++; 
          else
    
            s1='1'+s1; 
        }      
      } 
      return s1;    
    } 
    int main() 
    { 
      int n,T; 
      scanf("%d",&T); 
      while(T--) 
      { 
        string s;cin>>s; 
        if(s.size()==1)
    
        { 
          printf("1
    ");continue; 
        } 
        else if(s.size()==2) 
        { 
          printf("2
    ");continue; 
        } 
        string ans,a="1",b="2"; 
        for(int i=3;i<=s.size();i++) 
        { 
          ans=sum(a,b); 
          a=b; 
          b=ans; 
        } 
        cout<<b<<endl; 
      }    
      return 0; 
    }

    2)大数加减执行完毕后再对储存结果的result数组进行一次性进位(因为每位中两个十一上的数相加最多只进行一位累计结果不会造成数据范围溢出)

    eg:

                 8 1 3 5 7 3 8 7 2 5 8 9 7 1
    +        3 2 9 4 8 1 3 0 9 1 8 9 0 4 9 5 0 1 8

    = 3 2 9 4 8 9 4 3 (14) 8(11)(17)7 6(14)(13) 9 8 9
    最后进位,得:
          3 2 9 4 8 9 4 4 4 9 2 7 7 7 5 3 9 8 9

     code:

    #include <iostream>
    using namespace std;
    
    int a[1000],b[1000],result[1000];
    int main()
    {
      int t,i=1;
      while(cin>>t)
      a[i++]=t;  cin.clear();
    
      cin.sync();
    
      int j=1;
      while(cin>>t)
      b[j++]=t;
      
      int k,flag;
      if(i>j)
      {
    
         int len=i-j; 
         for(flag=k=i-1;k>=0;--k)
          result[k]=a[k]+b[k-len];
    
      } 
      else if(i<j)
      {
    
        int len=j-i; 
        for(flag=k=j-1;k>=0;--k)
          result[k]=b[k]+a[k-len];
    
      }
      else
      {
        for(flag=k=j-1;k>=0;--k)
          result[k]=b[k]+a[k];
      }
    
      for(int s=flag;s>=1;--s)
      {
        if(result[s]>9)
        {
          int t=result[s]%10;
          if(s-1)
            result[s-1]+=result[s]/10; 
          else
            result[s-1]=result[s]/10;
          result[s]=t;
        }
      }
    
      for(int s=0;s<=flag;++s)
        cout<<result[s];
      cout<<endl;
      return 0;
    }

    3)

    #include <stdio.h>
    int main()
    {
      char a[1001],b[1001],c[1002];
      int i,j,k,l;
      while(scanf("%s%s",a,b))
      {
        for(i=0;a[i];i++);
        for(j=0;b[j];j++); //把指针调整到加数、被加数最后一位,从个位数开始加
    
        for(k=c[1001]=0,l=1000;i||j||k;l--) //把相加结果从c[1000]--c[0]存储
        {
          c[l]=(i?a[i-1]:'0')+(j?b[j-1]:'0')+k-'0'; //做加法:A+b+进位
          k=0;
          if(c[l]>'9')
          {
            k=1;
            c[l]-=10; //处理进位
          }
          if(i)
            i--;
          if(j)
            j--;
        }
        printf("%s
    ",&c[l+1]);
      }
       return 0;
    }

     4)一个简单的进位模板

    int digit=0,num[1000][1000];
    
    for(int i=1;i<n;++i)//第几个数 
    {
      int temp,rem;//rem代表余数,每次计算余数初始化为0 
      rem=0;
      for(int j=0;j<digit;++j)
      {
        temp=num[i-1][j]+num[i-2][j]+rem;
        num[i][j]=temp%10;
        rem=temp/10;
      }
       while(rem)//如果j>digit且rem余数不为0,就代表向高位有进位, 
        {
          num[i][digit]=rem%10;//可能进位的数字较大不止一次进位,尝试多次处理 
          rem/=10;
          digit++;
        }
    }

    二:大数乘法

    如果两个大数为le1000,则乘机最大位数是le(1000+1000);,也就是长度两千的说数组。Max=2000即可。

    在大数乘法的过程中定义一个中间过程的2维数组,执行完毕后对每一列进行求和,得到结果,最后再对

    存储结果的result数组进行一次进位。

    code:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    class Solution
    {
    public:
        string multiply(string num1, string num2)
        {
            if(num1.empty()||num2.empty())
                return "";
            if(num1=="0"||num2=="0")
                return "0";
    
            vector<int> res(num1.size()+num2.size());
            for(int i=0,ii=num1.size()-1;i<num1.size(),ii>=0;++i,--ii)
            {
                for(int j=0,jj=num2.size()-1;j<num2.size(),jj>=0;++j,--jj)
                {
                    int sum_ij=i+j;
                    int tmp=(num1.at(ii)-'0')*(num2.at(jj)-'0')+res.at(sum_ij);
                    res.at(sum_ij)=tmp%10;
                    res.at(sum_ij+1)+=tmp/10;
                }
            }
    
            string result;
            for(auto i:res)
                result=to_string(i).append(result);
            if(result.at(0)=='0')
                return result.substr(1);
            return result;
        }
    };
    int main()
    {
        Solution s;
        string res(s.multiply("123","456"));
        cout<<res<<endl;
        return 0;
    }
  • 相关阅读:
    递归函数思想理解
    关于C++11 模板中的 using
    DES与3DES
    c++ 内存
    单词替换程序demo
    GF(256)下数的乘法 转化为矩阵乘法
    码片速率的含义
    转载 WCDMA中码片速率、符号速率、bit速率 WCDMA常用概念
    LTE 到GSM 的CCO过程是怎样的【转载自360】
    转载自搜狐科技【技术那些事儿】LTE网络中的用户数据库HSS与传统2G/3G的HLR有何区别?能否融合组网?
  • 原文地址:https://www.cnblogs.com/tianzeng/p/9020822.html
Copyright © 2011-2022 走看看