C++算法基礎之大整數類模板

用C++寫算法時,遇到高精度運算的問題,需要自己實現一個大整數類。苦於網上的大整數類參差不齊,我在參考的基礎上寫了一個大整數類,供參考理清思路。

參考:

  1. 《算法競賽入門經典》第五章大整數類
  2. 網上一些博客

思路:

  • 加法:逐位相加,處理進位
  • 減法:逐位相減,處理借位
  • 乘法:模擬手工乘法
  • 乘方:快速冪算法
  • 除法:模擬手工除法

注:這個大整數類在下面四題均測試通過。

例:以最後一題大整數除法爲例,它用到了大整數的加,減,乘,乘方運算。

main函數

#include <cstdio>
#include <cstring> 
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s[2];
	cin >> s[0] >> s[1];
	BigInteger a[2];
	for (int i = 0; i < 2; i++) {
		a[i] = s[i];
	}
	BigInteger c = a[0] / a[1];
	for (int i = c.length - 1; i >= 0; i--) {
		cout << c.big[i];
	}
	cout << endl;
	return 0;
}

BigInteger類

struct BigInteger {
	int big[1000];
	int length;
	BigInteger() {
		memset(big, 0, sizeof(big));
		length = 0;
	}
	BigInteger(long long num) {
		*this = num;
	}
	BigInteger(const string& str) {
		*this = str;
	}
	BigInteger operator = (long long num) {
		memset(big, 0, sizeof(big));
		length = 0;
		do {
			big[length++] = num % 10;
			num /= 10;
		} while (num);
		return *this;
	}
	BigInteger operator = (const string& str) {
		memset(big, 0, sizeof(big));
		length = str.size();
		for (int i = 0; i < length; i++) {
			big[i] = str[length - i - 1] - '0';
		}
		return *this;
	}
	bool operator < (const BigInteger& b) const {
		if (length != b.length)return length < b.length;
		for (int i = length - 1; i >= 0; i--) {
			if (big[i] != b.big[i])return big[i] < b.big[i];
		}
		return false;
	}
	bool operator > (const BigInteger& b) const { return b < *this; }
	bool operator <= (const BigInteger& b) const { return !(b < *this); }
	bool operator >= (const BigInteger& b) const { return !(*this < b); }
	bool operator != (const BigInteger& b) const { return b < *this || *this < b; }
	bool operator == (const BigInteger& b) const { return !(b < *this) && !(*this < b); }
	BigInteger operator + (const BigInteger& b) const {
		BigInteger c;
		int carry = 0;
		for (int i = 0; ; i++) {
			if (carry == 0 && i >= length && i >= b.length)break;
			int x = carry;
			if (i < length)x += big[i];
			if (i < b.length)x += b.big[i];
			c.big[c.length++] = x % 10;
			carry = x / 10;
		}
		return c;
	}
	BigInteger operator += (const BigInteger& b) {
		*this = *this + b;
		return *this;
	}
	BigInteger operator - (const BigInteger& b) const {// *this >= b
		BigInteger c;
		bool borrow = false;
		for (int i = 0; i < length; i++) {
			int x = borrow ? big[i] - 1 : big[i];
			if (x < b.big[i]) {
				borrow = true;
				x += 10;
			}
			else {
				borrow = false;
			}
			c.big[c.length++] += x - b.big[i];
		}
		while (c.big[c.length - 1] == 0 && c.length > 1)c.length--;
		return c;
	}
	BigInteger operator -= (const BigInteger& b) {
		*this = *this - b;
		return *this;
	}
	BigInteger operator * (const BigInteger& b) const {
		BigInteger c(0);
		for (int i = 0; i < length; i++) {
			BigInteger t;
			t.length = i;
			int carry = 0;
			for (int j = 0; j < b.length; j++) {
				int x = big[i] * b.big[j] + carry;
				t.big[t.length++] = x % 10;
				carry = x / 10;
			}
			if (carry) {
				t.big[t.length++] = carry;
			}
			c += t;
		}
		BigInteger e;
		e.length = c.length;
		if (c == e) {
			return BigInteger(0);
		}
		return c;
	}
	BigInteger operator *= (const BigInteger& b) {
		*this = *this * b;
		return *this;
	}
	BigInteger operator ^ (long long num) const {
		BigInteger b(*this);
		BigInteger c(1);
		while (num) {
			if ((num & 1) == 1) {
				c *= b;
			}
			b *= b;
			num >>= 1;
		}
		return c;
	}
	BigInteger operator / (const BigInteger& b) const {
		if (*this < b) {
			return BigInteger(0);
		}
		BigInteger c;
		BigInteger d(10);
		BigInteger m(*this);
		BigInteger n;
		int digit = length - b.length;
		for (int i = digit; i >= 0; i--) {
			n = b * (d ^ i);
			int j = 0;
			for ( ; ; j++) {
				if (m >= n) {
					m = m - n;
				}
				else {
					break;
				}
			}
			BigInteger t(j);
			c += t * (d ^ i);
		}
		return c;
	}
	BigInteger operator /= (const BigInteger& b) {
		*this = *this / b;
		return *this;
	}
};

說明:

  1. 聲明變量BigInteger c和BigInteger c(0)是不同的。前者沒有值,後者值爲0。
  2. 運算符 ^ 代表乘方運算,使用時需要注意它的優先級比 + - * / 低,要用括號括起來。
  3. 乘方運算右側的數字,即指數的類型爲long long,不是BigInteger類。
  4. 因爲負數無法用BigInteger類表示,做減法之前要作大小判斷,小數減大數結果未知。
  5. 本代碼供交流和學習之用,代碼問題可在下方留言。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章