过了好久才提交这道题目,重新写了个大数类,仿照别人写的,感觉还不错~
BigNumber的最后一题了
//#define LOCAL
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int const MAXN = 800;
class BigNumber
{
public:
int s[MAXN];
int len;
public:
// 去除前导零
void cleanLeadZero();
// 乘以10的n次方
void multiplyTen(int n);
// 除以10的n次方
void divisionTen(int n);
// 将结果转换成字符串
string str() const;
// 构造函数
BigNumber();
BigNumber(int);
BigNumber(const char *);
// 截取整数的前n位数(例如1234434 调用getSub(3)的话得到的结果是123)
BigNumber getSub(int n) const;
// 重载赋值运算符
BigNumber operator = (const char *);
BigNumber operator = (int num);
// 重载加减乘除
BigNumber operator + (const BigNumber &) const;
BigNumber operator - (const BigNumber &) const;
BigNumber operator * (const BigNumber &) const;
BigNumber operator / (const BigNumber &) const;
BigNumber operator % (const BigNumber &) const;
BigNumber operator -= (const BigNumber &);
BigNumber operator += (const BigNumber &);
BigNumber operator *= (const BigNumber &);
BigNumber operator /= (const BigNumber &);
// 重载比较运算符
bool operator < (const BigNumber &) const;
bool operator > (const BigNumber &) const;
bool operator <= (const BigNumber &) const;
bool operator >= (const BigNumber &) const;
bool operator == (const BigNumber &) const;
// 重载输入输出流
friend istream & operator >> (istream &, BigNumber &);
friend ostream & operator << (ostream &, BigNumber &);
};
void BigNumber::cleanLeadZero() {
while (len > 1 && !s[len - 1]) len--;
}
void BigNumber::divisionTen(int n)
{
int i;
if (n > len) {
while (len >= 1) s[len--] = 0;
} else {
for (i = 0; i < len - n; i++)
{
s[i] = s[i + n];
}
len -= n;
}
}
void BigNumber::multiplyTen(int n)
{
if (n > 0) {
int i;
for (i = len - 1; i >= 0; i--)
{
s[i + n] = s[i];
}
for (i = 0; i < n; i++) {
s[i] = 0;
}
len += n;
}
}
string BigNumber::str() const
{
string res = "";
// 每个位的数逆序添加到str末尾。
for (int i = 0; i < len; i++) {
res = (char)(s[i] + '0') + res;
}
if (res == "") res = "0";
return res;
}
BigNumber::BigNumber()
{
memset(s, 0, sizeof(s));
len = 1;
}
BigNumber::BigNumber(int num) {
*this = num;
}
BigNumber::BigNumber(const char * num) {
*this = num;
}
BigNumber BigNumber::getSub(int n) const
{
BigNumber c;
c.len = 0;
for (int i = 0; i < n; i++) {
c.s[c.len++] = s[len - n + i];
}
return c;
}
BigNumber BigNumber::operator = (const char * num)
{
len = strlen(num);
// 整数在s数组中是逆序存放的(如:"456" 在s数组中是s[0] = 6, s[1] = 5, s[2] = 4)
for (int i = 0; i < len; i++) {
s[i] = num[len - i - 1] - '0';
}
return *this;
}
BigNumber BigNumber::operator = (int num) {
char s[MAXN];
sprintf(s, "%d", num);
*this = s;
return *this;
}
BigNumber BigNumber::operator + (const BigNumber & x) const
{
BigNumber r;
r.len = 0;
// up 是用来保持进位的
int i, up;
int maxLen = max(len, x.len);
for (i = 0, up = 0; up || i < maxLen; i++) {
int temp = up;
if (i < len) temp += s[i];
if (i < x.len) temp += x.s[i];
up = temp / 10;
r.s[r.len++] = temp % 10;
}
// 去除前导零
r.cleanLeadZero();
return r;
}
// 减法在使用时要注意在计算a - b时要确保a >= b;
// 如果a < b 则计算 先输出一个'-' 再输出b - a 的结果
BigNumber BigNumber::operator - (const BigNumber & b) const
{
BigNumber c;
c.len = 0;
int i;
// 用来保存退位
int down;
for (i = 0, down = 0; i < len; i++)
{
int temp = s[i] - down;
if (i < b.len) temp -= b.s[i];
if (temp >= 0) down = 0;
else {
down = 1;
temp += 10;
}
c.s[c.len++] = temp;
}
c.cleanLeadZero();
return c;
}
BigNumber BigNumber::operator * (const BigNumber & b) const
{
int i, j;
BigNumber c;
c.len = len + b.len;
for (i = 0; i < len; i++) {
for (j = 0; j < b.len; j++) {
c.s[i + j] += s[i] * b.s[j];
}
}
for (i = 0; i < c.len - 1; i++) {
c.s[i + 1] += c.s[i] / 10;
c.s[i] %= 10;
}
c.cleanLeadZero();
return c;
}
BigNumber BigNumber::operator / (const BigNumber & b) const
{
int i, j;
BigNumber r;
r.len = 0;
// 模拟除法的过程
// 先取blen - 1位
BigNumber temp = this->getSub(b.len - 1);
// 一位一位的除从而取得完整的答案
for (i = len - b.len; i >= 0; i--)
{
// temp用来存储被除数的前blen位。
temp = temp * 10 + s[i];
// 如果temp < b则再在该位的结果为0
if (temp < b) {
r.s[r.len++] = 0;
} else {
// 否则找到第一个j使得b * j的结果大于 temp
for (j = 1; j <= 10; j++) {
if (b * j > temp) break;
}
// 因为此时(j - 1) * b小于等于temp,所有j - 1就是在该位除的结果
r.s[r.len++] = j - 1;
// temp 减去被减去部分为下一次迭代做准备
temp = temp - (b * (j - 1));
}
}
// 逆序(因为结果是要逆序存储的,而在求解过程中结果是顺序存储的)
for (i = 0; i < r.len / 2; i++) {
int temp = r.s[i];
r.s[i] = r.s[r.len - 1 - i];
r.s[r.len - 1 - i] = temp;
}
r.cleanLeadZero();
return r;
}
BigNumber BigNumber::operator % (const BigNumber & b) const
{
BigNumber r;
r = *this / b;
//cout << r << endl;
r = *this - r * b;
return r;
}
BigNumber BigNumber::operator += (const BigNumber & b)
{
*this = *this + b;
return *this;
}
BigNumber BigNumber::operator -= (const BigNumber & b)
{
*this = *this - b;
return *this;
}
BigNumber BigNumber::operator *= (const BigNumber & b)
{
*this = *this * b;
return *this;
}
BigNumber BigNumber::operator /= (const BigNumber & b)
{
*this = *this / b;
return *this;
}
bool BigNumber::operator < (const BigNumber & b) const
{
if (len != b.len) return len < b.len;
else {
for (int i = len - 1; i >= 0; i--) {
if (s[i] != b.s[i]) return s[i] < b.s[i];
}
}
return false;
}
bool BigNumber::operator > (const BigNumber & b) const
{
return b < *this;
}
bool BigNumber::operator <= (const BigNumber & b) const
{
return !(b > *this);
}
bool BigNumber::operator >= (const BigNumber & b) const
{
return !(*this < b);
}
bool BigNumber::operator == (const BigNumber & b) const
{
return !(b < *this) && !(b > *this);
}
istream & operator >> (istream & in, BigNumber & x)
{
string s;
in >> s;
x = s.c_str();
return in;
}
ostream & operator << (ostream & out, BigNumber & x)
{
out << x.str();
return out;
}
char a[1000];
char b[100];
char op;
int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
while (scanf("%s %c %s", a, &op, b) != EOF) {
BigNumber d(a);
BigNumber k(b);
d.cleanLeadZero();
k.cleanLeadZero();
if (op == '/') {
cout << (d / k).str() << endl;
} else {
cout << (d % k).str() << endl;
}
}
return 0;
}