ACM-大整数类-复习“紫书”

大整数的四则运算简单介绍


Ⅰ.思路

用数组来分段存储大整数。四则运算时利用模拟手算的方法来一步一步运算。为了方便,可以用结构体来存储大整数,并重新“定义”+ - × ÷ =运算符来计算大整数的四则运算。

下面时实现大整数加法的思路,其他的运算思想是一样的


Ⅱ-1.大整数赋值运算符 =

struct BigInteger {
	  static const int BASE = 100000000;	// 将大整数分割为8位数每节
	  static const int WIDTH = 8;	
	  vector<int> s;		// s数组就用来存储大整数
	
	  BigInteger(long long num = 0) {
		  	*this = num; 
	  } // 构造函数,声明变量时使用,其中0为默认值
	  BigInteger operator = (long long num) { 	// 赋值运算符
		    s.clear();
		    do {
			      s.push_back(num % BASE);	// 8位8位来存储
			      num /= BASE;
		    } while(num > 0);
		    return *this;
	  }
}
/*
例如1234567887654321这个大整数存在s数组中为:
s[0] = 87654321;
s[1] = 12345678;
*/

Ⅱ-2.定义">>" "<<"运算符

// 下麦呢代码也写在BigInteger结构体中
ostream& operator << (ostream &out, const BigInteger& x) {	// <<运算符
  out << x.s.back();	// 输出大整数最后一个分段
  for(int i = x.s.size()-2; i >= 0; i--) {	// 若有,从大整数倒数第二个分段开始输出
    char buf[20];
    sprintf(buf, "%08d", x.s[i]);	// 8位一段
    for(int j = 0; j < strlen(buf); j++) {	// 逐个数字打印出
    	out << buf[j];
    }
  }
  return out;
}
/*
如1234567887654321这个大整数输出过程为:
87654321
887654321
7887654321
...
...
1234567887654321
*/
istream& operator >> (istream &in, BigInteger& x) {	// >>运算符
  string s;
  if(!(in >> s)) return in;
  x = s;
  return in;
}

Ⅱ-3.定义"+"运算符

// 下麦呢代码也写在BigInteger结构体中
BigInteger operator + (const BigInteger& b) const {
	BigInteger c;
	c.s.clear();
	for(int i = 0, g = 0; ; i++) {
		if(g == 0 && i >= s.size() && i >= b.s.size()) 
			break;
		int x = g;
		if(i < s.size()) x += s[i];
		if(i < b.s.size()) x += b.s[i];
		c.s.push_back(x % BASE);
		g = x / BASE;
	}
return c;

Ⅲ.完整代码

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

struct BigInteger {
  static const int BASE = 100000000;
  static const int WIDTH = 8;
  vector<int> s;

  BigInteger(long long num = 0) { *this = num; } // 构造函数
  BigInteger operator = (long long num) { // 赋值运算符
    s.clear();
    do {
      s.push_back(num % BASE);
      num /= BASE;
    } while(num > 0);
    return *this;
  }
  BigInteger operator = (const string& str) { // 赋值运算符
    s.clear();
    int x, len = (str.length() - 1) / WIDTH + 1;
    for(int i = 0; i < len; i++) {
      int end = str.length() - i*WIDTH;
      int start = max(0, end - WIDTH);
      sscanf(str.substr(start, end-start).c_str(), "%d", &x);
      s.push_back(x);
    }
    return *this;
  }
  BigInteger operator + (const BigInteger& b) const {
    BigInteger c;
    c.s.clear();
    for(int i = 0, g = 0; ; i++) {
      if(g == 0 && i >= s.size() && i >= b.s.size()) break;
      int x = g;
      if(i < s.size()) x += s[i];
      if(i < b.s.size()) x += b.s[i];
      c.s.push_back(x % BASE);
      g = x / BASE;
    }
    return c;
  }
};

ostream& operator << (ostream &out, const BigInteger& x) {
  out << x.s.back();
  for(int i = x.s.size()-2; i >= 0; i--) {
    char buf[20];
    sprintf(buf, "%08d", x.s[i]);
    for(int j = 0; j < strlen(buf); j++) out << buf[j];
  }
  return out;
}

istream& operator >> (istream &in, BigInteger& x) {
  string s;
  if(!(in >> s)) return in;
  x = s;
  return in;
}



int main() {
  // 三个测试数据 
  BigInteger y;
  BigInteger z = 123456789987654321;
  BigInteger x = z;
  // 测试加法运算
  BigInteger a, b;
  cout << "Please input two bigintegers :";
  cin >> a >> b;
  cout << "a + b = " << a + b << "\n";
  cout << "y = " << y << endl<< "z = " << z << endl << "x = " << x << endl;
  return 0;
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值