首先是遇到了1017 A除以B,稀里糊涂地复制了别人的答案就将其抛在脑后(偶然事件),紧接着就遇到了1022 D进制的A+B,这时突然记起学习要有打破砂锅问到底的精神,根本不是因为发现这个问题逃避不了,开始了对这个知识点的研究学习。
-
取余运算
取余就是取模,可以将其转换为对字符串中的最低数位进行取模运算。
-
整除运算
对于整除运算,需要重新写一个函数来完成字符串的除法功能。
实现字符串除法函数的做法和日常在纸上实现除法的做法是一样的,即把字符中从商到低逐位除以除数。如界某位不能整除,那么就保留它除以除数的余数,余数乘以 10 后和低一位一起进行处理。这样,就能模拟出除法的效果,但这种做法可能会前置多余的 0,这时只需取首个非0位之后的字符串,便可得到想要的结果。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<vector>
using namespace std;int toBinary(unsigned int n) {//被转换十进制数在int范围内vector<int> binary;//用vector装,跟用数组装都一样while (n != 0) {//一直除,直到等于零binary.push_back(n % 2);//将取模的值压进vectorn /= 2;//数字也除进制数}for (int i = binary.size() - 1; i >= 0; i--)cout << binary[i];//由于采用头插法,数字是倒着的,需逆序输出cout << endl;
}/*
* 当被转换数字只能用长字符串表示时,同样地,对此字符串不断进行对2取模和对2整除运算。不同的是,
* 1. 对于取模运算,可以将其转换为对字符串中的最低数位进行取模运算。
* 2. 对于整除运算,需要重新写一个函数来完成字符串的除法功能。实现字符串除法函数的做法和日常在纸上实现除法的做法是一样的,即把字符中从商到低逐位除以除数。
* 如界某位不能整除,那么就保留它除以除数的余数,余数乘以 10 后和低一位一起进行处理。这样,就能模拟出除法的效果,但这种做法可能会前置多余的 0,这时只需取首个
* 非0位之后的字符串,便可得到想要的结果。
*/string Divide(string s, int x) {//整除运算函数int remainder = 0;for (int i = 0; i < s.size(); ++i) {int current = remainder * 10 + s[i] - '0';s[i] = current / x + '0';remainder = current % x;}int pos = 0;while (s[pos] == '0')pos++;return s.substr(pos);
}int main() {return 0;
}
上面也就看一乐,接下来是书上的代码,书上成为高精度整数,Java中有BigInteger类可以直接用,这里给出一系列模板。注意这个模板只适用于运算数和运算结果均为正整数的运算,否则会出错。
const int MAXN = 10000;//定义常量MAXN表示最大位数,即最多能表示的数字位数struct BigInteger {int digit[MAXN];//用于存储大整数的每一位数字int length;//表示大整数的位数BigInteger();//⭐BigInteger(int x);//构造函数,接受一个整数 x 并将其转换为大整数类型BigInteger(string str);//⭐构造函数,接受一个字符串 str,并将其转换为大整数类型BigInteger(const BigInteger& b);//构造函数,接受另外一个大整数类型的对象 b,并将其复制为新的大整数类型BigInteger operator=(int x);//重载赋值运算符,将一个整数类型的值赋值给大整数类型对象BigInteger operator=(string str);//重载赋值运算符,将一个字符串类型的值赋值给大整数类型对象BigInteger operator=(const BigInteger& b);//重载赋值运算符,将另外一个大整数类型的对象赋值给当前对象bool operator <= (const BigInteger& b);//判断当前大整数类型对象是否小于等于另外一个大整数类型对象bool operator == (const BigInteger& b);//判断当前大整数类型对象是否等于另外一个大整数类型对象BigInteger operator+(const BigInteger& b);//重载加法运算符,实现大整数的 + 法BigInteger operator-(const BigInteger& b);//重载减法运算符,实现大整数的 - 法BigInteger operator*(const BigInteger& b);//重载乘法运算符,实现大整数的 * 法BigInteger operator/(const BigInteger& b);//重载除法运算符,实现大整数的 / 法BigInteger operator%(const BigInteger& b);//重载取模运算符,实现大整数取模friend istream& operator>>(istream& in, BigInteger& x);//⭐重载输入运算符,用于将用户输入的字符串或整数转换为大整数类型friend ostream& operator<<(ostream& out, const BigInteger& x);//⭐重载输出运算符,用于输出大整数类型对象
};//该结构体的作用是用于实现大整数的基本运算,方便用户直接进行大整数的计算istream& operator>>(istream& in, BigInteger& x) {//string str;in >> str;x = str;return in;
}ostream& operator<<(ostream& out, const BigInteger& x) {for (int i = x.length - 1; i >= 0; --i)out << x.digit[i];return out;
}BigInteger::BigInteger() {memset(digit, 0, sizeof(digit));length = 0;
}BigInteger::BigInteger(int x) {memset(digit, 0, sizeof(digit));length = 0;if (x == 0) digit[length++] = x;while (x != 0) {digit[length++] = x % 10;x /= 10;}
}BigInteger::BigInteger(string str){memset(digit, 0, sizeof(digit));length = str.size();for (int i = 0; i < length; ++i)digit[i] = str[length - i - 1] - '0';
}BigInteger::BigInteger(const BigInteger& b){memset(digit, 0, sizeof(digit));length = b.length;for (int i = 0; i < length; ++i)digit[i] = b.digit[i];
}BigInteger BigInteger::operator=(int x)
{ memset(digit, 0, sizeof(digit));length = 0;if (x == 0) digit[length++] = x;while (x) {digit[length++] = x % 10;x /= 10;}return *this;
}BigInteger BigInteger::operator=(string str){memset(digit, 0, sizeof(digit));length = str.size();for (int i = 0; i < length; ++i)digit[i] = str[length - i - 1] - '0';return *this;
}BigInteger BigInteger::operator=(const BigInteger& b){memset(digit, 0, sizeof(digit));length = b.length;for (int i = 0; i < length; ++i)digit[i] = b.digit[i];return *this;
}bool BigInteger::operator<=(const BigInteger& b){if (length < b.length) return true;else if (length > b.length) return false;elsefor (int i = length - 1; i >= 0; --i) {if (digit[i] == b.digit[i]) continue;else return digit[i] < b.digit[i];}return true;
}bool BigInteger::operator==(const BigInteger& b){if (length != b.length) return false;elsefor (int i = length - 1; i >= 0; --i)if (digit[i] != b.digit[i]) return false;return true;
}BigInteger BigInteger::operator+(const BigInteger& b){BigInteger answer;int carry = 0;for (int i = 0; i < length || i < b.length; ++i) {int current = carry + digit[i] + b.digit[i];carry = current / 10;answer.digit[answer.length++] = current % 10;}if (carry != 0) answer.digit[answer.length++] = carry;return answer;
}BigInteger BigInteger::operator-(const BigInteger& b){BigInteger answer;int carry = 0;for (int i = 0; i < length; ++i) {int current = digit[i] - b.digit[i] - carry;if (current < 0) {current += 10;carry = 1;}else {carry = 0;}answer.digit[answer.length++] = current;}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator*(const BigInteger& b){BigInteger answer;answer.length = length + b.length;for (int i = 0; i < length; ++i)for (int j = 0; j < b.length; ++j)answer.digit[i + j] += digit[i] * b.digit[j];for (int i = 0; i < answer.length; ++i) {answer.digit[i + 1] += answer.digit[i] / 10;answer.digit[i] %= 10;}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator/(const BigInteger& b){BigInteger answer;answer.length = length;BigInteger remainder = 0, temp = b;for (int i = length - 1; i >= 0; --i) {if (!(remainder.length == 1 && remainder.digit[0] == 0)) {for (int j = remainder.length - 1; j >= 0; --j)remainder.digit[j + 1] = remainder.digit[j];remainder.length++;}remainder.digit[0] = digit[i];while (temp <= remainder) {remainder = remainder - temp;answer.digit[i]++;}}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator%(const BigInteger& b){BigInteger remainder = 0;BigInteger temp = b;for (int i = length - 1; i >= 0; --i) {if (!(remainder.length == 1 && remainder.digit[0] == 0)) {for (int j = remainder.length - 1; j >= 0; --j)remainder.digit[j + 1] = remainder.digit[j];remainder.length++;}remainder.digit[0] = digit[i];while (temp <= remainder)remainder = remainder - temp;}return remainder;
}
画⭐的是必写的模板,其他的需要用到才写。
真不知道怎么错的,但是A+B的D进制这一题就是没对。跟书写的一样了,但是不理解代码,只能机械地对比,可能书上也有小错误,但是我没发现了。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<vector>using namespace std;const int MAXN = 10000;//定义常量MAXN表示最大位数,即最多能表示的数字位数struct BigInteger {int digit[MAXN];//用于存储大整数的每一位数字int length;//表示大整数的位数BigInteger();BigInteger(int x);//构造函数,接受一个整数 x 并将其转换为大整数类型BigInteger(string str);//构造函数,接受一个字符串 str,并将其转换为大整数类型BigInteger(const BigInteger& b);//构造函数,接受另外一个大整数类型的对象 b,并将其复制为新的大整数类型BigInteger operator=(int x);//重载赋值运算符,将一个整数类型的值赋值给大整数类型对象BigInteger operator=(string str);//重载赋值运算符,将一个字符串类型的值赋值给大整数类型对象BigInteger operator=(const BigInteger& b);//重载赋值运算符,将另外一个大整数类型的对象赋值给当前对象bool operator <= (const BigInteger& b);//判断当前大整数类型对象是否小于等于另外一个大整数类型对象bool operator == (const BigInteger& b);//判断当前大整数类型对象是否等于另外一个大整数类型对象bool operator != (const BigInteger& b);BigInteger operator+(const BigInteger& b);//重载加法运算符,实现大整数的 + 法BigInteger operator-(const BigInteger& b);//重载减法运算符,实现大整数的 - 法BigInteger operator*(const BigInteger& b);//重载乘法运算符,实现大整数的 * 法BigInteger operator/(const BigInteger& b);//重载除法运算符,实现大整数的 / 法BigInteger operator%(const BigInteger& b);//重载取模运算符,实现大整数取模friend istream& operator>>(istream& in, BigInteger& x);//重载输入运算符,用于将用户输入的字符串或整数转换为大整数类型friend ostream& operator<<(ostream& out, const BigInteger& x);//重载输出运算符,用于输出大整数类型对象
};//该结构体的作用是用于实现大整数的基本运算,方便用户直接进行大整数的计算istream& operator>>(istream& in, BigInteger& x) {//string str;in >> str;x = str;return in;
}ostream& operator<<(ostream& out, const BigInteger& x) {for (int i = x.length - 1; i >= 0; --i)out << x.digit[i];return out;
}BigInteger::BigInteger() {memset(digit, 0, sizeof(digit));length = 0;
}BigInteger::BigInteger(int x) {memset(digit, 0, sizeof(digit));length = 0;if (x == 0) digit[length++] = x;while (x != 0) {digit[length++] = x % 10;x /= 10;}
}BigInteger::BigInteger(string str){memset(digit, 0, sizeof(digit));length = str.size();for (int i = 0; i < length; ++i)digit[i] = str[length - i - 1] - '0';
}BigInteger::BigInteger(const BigInteger& b){memset(digit, 0, sizeof(digit));length = b.length;for (int i = 0; i < length; ++i)digit[i] = b.digit[i];
}BigInteger BigInteger::operator=(int x)
{ memset(digit, 0, sizeof(digit));length = 0;if (x == 0) digit[length++] = x;while (x != 0) {digit[length++] = x % 10;x /= 10;}return *this;
}BigInteger BigInteger::operator=(string str){memset(digit, 0, sizeof(digit));length = str.size();for (int i = 0; i < length; ++i)digit[i] = str[length - i - 1] - '0';return *this;
}BigInteger BigInteger::operator=(const BigInteger& b){memset(digit, 0, sizeof(digit));length = b.length;for (int i = 0; i < length; ++i)digit[i] = b.digit[i];return *this;
}bool BigInteger::operator<=(const BigInteger& b){if (length < b.length) return true;else if (length > b.length) return false;elsefor (int i = length - 1; i >= 0; --i) {if (digit[i] == b.digit[i]) continue;else return digit[i] < b.digit[i];}return true;
}bool BigInteger::operator==(const BigInteger& b){if (length != b.length) return false;elsefor (int i = length - 1; i >= 0; --i)if (digit[i] != b.digit[i]) return false;return true;
}bool BigInteger::operator!=(const BigInteger& b){if (length != b.length) return true;elsefor (int i = length - 1; i >= 0; --i)if (digit[i] != b.digit[i]) return true;return false;
}BigInteger BigInteger::operator+(const BigInteger& b){BigInteger answer;int carry = 0;for (int i = 0; i < length || i < b.length; ++i) {int current = carry + digit[i] + b.digit[i];carry = current / 10;answer.digit[answer.length++] = current % 10;}if (carry != 0) answer.digit[answer.length++] = carry;return answer;
}BigInteger BigInteger::operator-(const BigInteger& b){BigInteger answer;int carry = 0;for (int i = 0; i < length; ++i) {int current = digit[i] - b.digit[i] - carry;if (current < 0) {current += 10;carry = 1;}else {carry = 0;}answer.digit[answer.length++] = current;}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator*(const BigInteger& b){BigInteger answer;answer.length = length + b.length;for (int i = 0; i < length; ++i)for (int j = 0; j < b.length; ++j)answer.digit[i + j] += digit[i] * b.digit[j];for (int i = 0; i < answer.length; ++i) {answer.digit[i + 1] += answer.digit[i] / 10;answer.digit[i] %= 10;}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator/(const BigInteger& b){BigInteger answer;answer.length = length;BigInteger remainder = 0, temp = b;for (int i = length - 1; i >= 0; --i) {if (!(remainder.length == 1 && remainder.digit[0] == 0)) {for (int j = remainder.length - 1; j >= 0; --j)remainder.digit[j + 1] = remainder.digit[j];remainder.length++;}remainder.digit[0] = digit[i];while (temp <= remainder) {remainder = remainder - temp;answer.digit[i]++;}}while (answer.digit[answer.length] == 0 && answer.length > 1)answer.length--;return answer;
}BigInteger BigInteger::operator%(const BigInteger& b){BigInteger remainder = 0;BigInteger temp = b;for (int i = length - 1; i >= 0; --i) {if (!(remainder.length == 1 && remainder.digit[0] == 0)) {for (int j = remainder.length - 1; j >= 0; --j)remainder.digit[j + 1] = remainder.digit[j];remainder.length++;}remainder.digit[0] = digit[i];while (temp <= remainder)remainder = remainder - temp;}return remainder;
}int main() {BigInteger a, b, d;cin >> a >> b >> d;BigInteger n = a + b;vector<BigInteger> jieguo;if (d == 10) {cout << n << endl; return 0;}while (n != 0) {cout << n % d << "这是取余\n";jieguo.push_back(n % d);cout << n << "这是n\n";cout << d << "这是d\n";n = n / d;cout << n << "这是除法\n";}for (int i = jieguo.size() - 1; i >= 0; --i) {cout << jieguo[i];}cout << endl;return 0;
}