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
  • 相关阅读:
    【ASP.NET 进阶】根据IP地址返回对应位置信息
    【网络文摘】编程的智慧
    【ASP.NET 类库】当你懒得用 Json+Ajax 时,可以试试 AjaxPro
    【iOS 初见】第一个简单的 iOS 应用
    【C#】C# 实现发送手机短信
    【网络文摘】一家公司要了你后,凭什么给你开高工资?
    深入理解Java虚拟机01--概述
    Java虚拟机(五)Java的四种引用级别
    OkHttp3源码详解(六) Okhttp任务队列工作原理
    OkHttp3源码详解(五) okhttp连接池复用机制
  • 原文地址:https://www.cnblogs.com/dlvguo/p/9735585.html
Copyright © 2011-2022 走看看