1. 程式人生 > >C++高精度演算法—大數加大數,大數乘以小數

C++高精度演算法—大數加大數,大數乘以小數

一次偶然的機會,看到百度面試題中出現了很多關於處理大資料的處理題目,也稱作高精度題目,另外在ACM競賽中也偶爾會碰到。我們知道在C語言或C++語言中,通常受機器字長的限制,我們會碰到如果某個整數的範圍超過一個範圍就沒法運算。這時我們只能先用字串讀進去,然後再將字元型的“數”轉換成數值的“數”,再模擬手算,一位一位相加,最後得到結果。

具體請看下面的例子:

#include <iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;

/*****任務:高精度,計算大數乘以小數
******引數:被乘數a[],乘數b;
******結果儲存在a[]中***************/
int Mul(char a[],int b)
{
    int i,j,len;
    char tmp[1000];
    len=strlen(a);
    for(i=0;i<len;i++)
    tmp[len-i-1]=a[i]-'0';              //將字元陣列a轉換成整型陣列,並逆序記錄在tmp中
    int c=0,s;
    for(j=0;j<len;j++)                  //模擬人工手算
    {
        s=tmp[j]*b+c;                   //記錄每次相乘的結果(包括進位)
        tmp[j]=s%10;
        c=s/10;
    }
    while(c)                            //對資料位數修正
    {
        tmp[len++]=c%10;
        c/=10;
    }
    for(i=0;i<len;i++)
    a[i]=tmp[len-1-i]+'0';              //再次逆序並換成字元陣列
    for(i=0;i<len;i++)
    cout<<a[i];
    cout<<endl;
    return 0;
}
/****高精度:大數加大數模板
*****引數:兩個字元陣列a[],b[]
*****結果儲存在ans[]中*********/
int add(char a[],char b[])
{
         int i,j,s,len,c=0;
         char ans[10000];
         int temp_a[10000],temp_b[10000],temp_ans[10000];
         memset(ans,0,sizeof(ans));
         memset(temp_a,0,sizeof(temp_a));
         memset(temp_b,0,sizeof(temp_b));
         memset(temp_ans,0,sizeof(temp_ans));
         len=max(strlen(a),strlen(b));
         for (i=0;i<strlen(a);i++)
            temp_a[strlen(a)-i-1]=a[i]-'0';//字元陣列轉換為整型陣列
         for (i=0;i<strlen(b);i++)
            temp_b[strlen(b)-i-1]=b[i]-'0';

         for(j=0;j<len;j++)               //模擬手算
         {
            s=temp_a[j]+temp_b[j]+c;
            temp_ans[j]=s%10;
            c=s/10;
         }
         if(c) temp_ans[len++]=c;       //資料位數修正
         for (i=0;i<len;i++)            //整型陣列轉字元陣列
            ans[len-1-i]=temp_ans[i]+'0';
        for(int i=0;i<len;i++)          //輸出結果
            cout<<ans[i];
         cout<<endl;
        }
int main()
{
    char a[1000],b[1000];
    int m;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    cout<<"模擬大數乘以小數:"<<endl;
    cin>>a>>m;
    Mul(a,m);
    cout<<"模擬大數加大數: "<<endl;
    cin>>a>>b;
    add(a,b);
    return 0;
}

程式執行結果:


通過這個例子,可以解決一般的大數相加問題,同時只要稍作調整,也可以寫出大數乘以大數,大數階乘,大數除以大數的相應演算法。