用C++寫算法時,遇到高精度運算的問題,需要自己實現一個大整數類。苦於網上的大整數類參差不齊,我在參考的基礎上寫了一個大整數類,供參考理清思路。
參考:
- 《算法競賽入門經典》第五章大整數類
- 網上一些博客
思路:
- 加法:逐位相加,處理進位
- 減法:逐位相減,處理借位
- 乘法:模擬手工乘法
- 乘方:快速冪算法
- 除法:模擬手工除法
注:這個大整數類在下面四題均測試通過。
例:以最後一題大整數除法爲例,它用到了大整數的加,減,乘,乘方運算。
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;
}
};
說明:
- 聲明變量BigInteger c和BigInteger c(0)是不同的。前者沒有值,後者值爲0。
- 運算符 ^ 代表乘方運算,使用時需要注意它的優先級比 + - * / 低,要用括號括起來。
- 乘方運算右側的數字,即指數的類型爲long long,不是BigInteger類。
- 因爲負數無法用BigInteger類表示,做減法之前要作大小判斷,小數減大數結果未知。
- 本代碼供交流和學習之用,代碼問題可在下方留言。