1. 程式人生 > >大整數加法計算思路與演算法實現

大整數加法計算思路與演算法實現

參加MOOC PKU的程式設計專項課程學習,目前進度到C++。這門課太爛了,完全就是自學,作業還相當難!!!!比如這裡week4的這題,其實是把poj上的大整數的加、減、乘、除合併到一題裡面,這個程式碼量很恐怖。當然了,通過查詢相關資料,終於學習了,如何實現大整數的高精度四則運算,這也是程式設計師面試的一道經典題。其實具體的思路就是小學豎式計算,但是程式碼實現的過程,比較抽象。先說說大整數加法。

0、編寫大整數類結構

使用陣列儲存所有運算元,定義陣列大小200。定義一個全域性變數,存運算子,因為減法運算中有可能需要輸出負號。定義一個布林變數,用於區分減法的三種情況。

#include <iostream>
#include<cstring>
#include<cstdlib>
#define MAX_LEN 200
char o;                              /*全域性運算子*/
bool cannotSub=0;                    /*不夠減標記,區分減法的情況*/
char szLine1[MAX_LEN+10]={0};         /*輸入輸出的字元陣列*/
char szLine2[MAX_LEN+10]={0};

成員變數2個。一個是陣列的首地址,用整型指標。另一個是儲存陣列的大小,用int型。
成員函式包括建構函式、賦值號過載函式以及四則運算子號的過載函式和一個倍增函式(用於將數擴大為原來的10n倍)。

class  bigNum
    {
    public:
        bigNum():sInt(NULL){ len=0; }    /*建構函式*/
        ~bigNum(){ if(sInt)    delete[] sInt; }/*解構函式*/
        const int * getint(){ return sInt; }  /*返回陣列首地址*/
        bigNum & operator
= (char *s); /*賦值號過載函式*/ bigNum & operator= (bigNum & b); /*實現深複製,即指向內容之間的複製*/ friend void operator+ (bigNum & result,bigNum & b);/*加號過載*/ friend void operator- (bigNum & result,bigNum & b);/*減號過載*/ friend void operator* (bigNum & result,bigNum & b);/*乘號過載*/
friend void operator/ (bigNum & result,bigNum & b);/*除號過載*/ friend void multi10 (bigNum & b,int n);/*倍增函式*/ private: int *sInt; /*實際進行四則運算的整型數*/ int len; /*陣列長度*/ };

賦值號過載函式的作用,

  • 1、是實現主函式中字串儲存為整型陣列,因為用主函式中定義了char型陣列cin輸入的是ASCII碼,需要減去’0’的ASCII碼再儲存為整型陣列。輸入用字元陣列,因為有一些函式可以直接使用,如求字串長度等等。
  • 2、是實現物件之間的深複製,也就是物件所指向內容之間的拷貝。
  • 3、是實現動態分配陣列的儲存空間。

一、大整數加法

1、思路

大整數加法的思路,就是豎式計算,逐項相加。考慮進位,就是逢十進一,也就是說如果某一位大於等於10,減去10就是本位和,然後下一位++,這就是進位。加法最多就是進1位

2種情況.不進位加法:

 1234

+4321

5555 

進位加法

 999

+888

887

2、 演算法

運用陣列儲存兩個加數,右對齊逐位相加,如果和大於或等於10,和減10,同時下一位被加數++。

/*加號過載,實現result+b*/
    void operator+ (bigNum & result,bigNum & b)
    {
        for( int i = 0;i < MAX_LEN+10 ; i ++ )
        {
             result.sInt[i] += b.sInt[i]; //逐位相加
             if( result.sInt[i] >= 10 )
                 { //看是否要進位
                result.sInt[i] -= 10; //本位和
                result.sInt[i+1] ++; //下一位進位
             }
        }
    }