zoukankan      html  css  js  c++  java
  • 大数运算

    在计算中,如果运算数值超过自带整型的范围,则会溢出。因此在这类计算中,通常把数存放在数组中。进行运算。

    1、大数阶乘(相乘)

      在N!中的计算中首先先计数出N!的位数。设位数为m。则

        pow(10,m-1)<=N!<=pow(10,m)-1<pow(10,m)。    

        m-1<=log10(N)<m

        m=log10(2)+log10(3)...........+log10(N)+1

      贴上计算代码 

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 int a[500000];
     8 
     9 void reset(int m){
    10     for(int i=0;i<=m;i++)
    11         a[i]=0;
    12 }
    13 
    14 void countn(int num,ll t){
    15     int k=0;
    16     a[0]=1;
    17     for(ll i=2;i<=t;i++)
    18         for(int j=0;j<num;j++){
    19             a[j]*=i;
    20             a[j]+=k;
    21             k=a[j]/10;
    22             a[j]%=10;
    23         }
    24     for(int i=num-1;i>=0;i--)
    25         cout<<a[i];
    26     cout<<endl;
    27 
    28 }
    29 
    30 int main(){
    31     ll t,num=1;
    32     double m;
    33     while(cin>>t){
    34         m=0;
    35         for(int i=2;i<=t;i++)
    36             m+=log10(i);
    37         num=(int)m+1;
    38         reset(num);
    39         countn(num,t);
    40     }
    41 
    42 
    43 }
    View Code

      大数相乘

     1 #include<iostream>
     2 #include<math.h>
     3 #include<string.h>>
     4 using namespace std;
     5 
     6 void reset(int *m,int length){
     7     for(int i=0;i<length;i++)
     8         m[i]=0;
     9 }
    10 
    11 int main(){
    12     string M,N;
    13     int m[10000],n[10000];
    14     cin>>M;
    15     cin>>N;
    16     int m_len=M.length();
    17     int n_len=N.length();
    18     int total=m_len+n_len;
    19     int mul[total];
    20     for(int i=0;i<m_len;i++){
    21         m[i]=M[m_len-1-i]-48;
    22     }
    23     for(int i=0;i<n_len;i++){
    24         n[i]=N[n_len-1-i]-48;
    25     }
    26 
    27     reset(mul,total);
    28     for(int i=0;i<n_len;i++){
    29         for(int j=0;j<m_len;j++){
    30              int index=j+i;
    31              mul[index]+=n[i]*m[j];
    32              mul[index+1]+=mul[index]/10;
    33              mul[index]%=10;
    34         }
    35     }
    36     if(mul[total-1]==0)
    37         total--;
    38     for(int i=total-1;i>=0;i--)
    39         cout<<mul[i];
    40     return 0;
    41 }
    View Code

    2、大数相加(相减类似)

      首先找出俩个数最大的那个,对齐,从个位依次相加。逢10进一,依次类推。

      大数相加

     1 #include<iostream>
     2 #include<string.h>
     3 using namespace std;
     4 
     5 int main(){
     6     string M,N;
     7     int m[10000],n[10000];
     8     cin>>M;
     9     cin>>N;
    10     int m_len=M.length();
    11     int n_len=N.length();
    12     int total=m_len>n_len?m_len:n_len;
    13     memset(m,0,total);
    14     memset(n,0,total);
    15     for(int i=0;i<m_len;i++){
    16         m[i]=M[m_len-1-i]-48;
    17     }
    18     for(int i=0;i<n_len;i++){
    19         n[i]=N[n_len-1-i]-48;
    20     }
    21     int carry=0;
    22     for(int i=0;i<total;i++){
    23         m[i]=m[i]+n[i]+carry;
    24         if(m[i]>9){
    25             m[i]%=10;
    26             carry=1;
    27         }
    28         else{
    29             carry=0;
    30         }
    31     }
    32     if(carry==1)
    33         cout<<"1";
    34         for(int i=total-1;i>=0;i--){
    35             cout<<m[i];
    36     }
    37 }
    View Code

      大数相减

     1 #include<iostream>
     2 #include<string.h>
     3 using namespace std;
     4 
     5 void printSub(int *a,int *b,int length,bool isBig){
     6     int carry=0;
     7     for(int i=0;i<length;i++){
     8         if(a[i]<b[i]+carry){
     9             a[i]=a[i]+10-b[i]-carry;
    10             carry=1;
    11         }
    12         else{
    13             a[i]=a[i]-b[i]-carry;
    14             carry=0;
    15         }
    16     }
    17     if(!isBig)
    18     cout<<"-";
    19     if(a[length-1]==0)
    20         length--;
    21     for(int i=length-1;i>=0;i--){
    22         cout<<a[i];
    23     }
    24 }
    25 
    26 int main(){
    27     string M,N;
    28     int m[10000],n[10000];
    29     cin>>M;
    30     cin>>N;
    31     int m_len=M.length();
    32     int n_len=N.length();
    33     bool isBig=m_len>=n_len?true:false;
    34     int total=isBig?m_len:n_len;
    35     memset(m,0,total);
    36     memset(n,0,total);
    37      for(int i=0;i<m_len;i++){
    38         m[i]=M[m_len-1-i]-48;
    39     }
    40     for(int i=0;i<n_len;i++){
    41         n[i]=N[n_len-1-i]-48;
    42     }
    43     if(isBig)
    44         printSub(m,n,total,isBig);
    45     else
    46         printSub(n,m,total,isBig);
    47     return 0;
    48 }
    View Code

    3、大数相除

      一般大数相除中,常见的思路是

      例如8888/300

      300*10=3000

      3000*2=6000

      依次类推,则算出商为29,余数为188,可以考虑采取二分法进行判断,获取最大的整数倍数分析。

      如果除数为能用int表示的变量,则从首位依次类推,下面列出例子:

     1 #include<iostream>
     2 #include<math.h>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 int main(){
     7     int d,remainder;
     8     string m;
     9     cin>>m;
    10     cin>>d;
    11     int m_len=m.length();
    12     int arr[m_len],quo[m_len];
    13     for(int i=0;i<m_len;i++){
    14         arr[i]=m[i]-48;
    15         }
    16     int divisor=0,index=0,q_index=0;
    17     while(index<m_len){
    18         divisor=divisor*10+arr[index];
    19         if(divisor<d){
    20             quo[q_index]=0;
    21         }
    22         else{
    23             quo[q_index]=divisor/d;
    24             divisor%=d;
    25         }
    26         index++;
    27         q_index++;
    28     }
    29     for(int i=0;i<q_index;i++)
    30     {
    31         if(quo[i]!=0){
    32             index=i;
    33             break;
    34         }
    35     }
    36     if(index==q_index-1)
    37         cout<<"0";
    38     else
    39         for(int i=index;i<q_index;i++)
    40             cout<<quo[i];
    41     return 0;
    42 }
    View Code
  • 相关阅读:
    -bash: fork: Cannot allocate memory 问题的处理
    Docker top 命令
    docker常见问题修复方法
    The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
    What's the difference between encoding and charset?
    hexcode of é î Latin-1 Supplement
    炉石Advanced rulebook
    炉石bug反馈
    Sidecar pattern
    SQL JOIN
  • 原文地址:https://www.cnblogs.com/dlvguo/p/9735585.html
Copyright © 2011-2022 走看看