首先是遇到了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);//将取模的值压进vector
n /= 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;
else
for (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;
else
for (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;
else
for (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;
else
for (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;
else
for (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;
}
标签:BigInteger,运算,int,digit,整数,length,answer,remainder
From: https://www.cnblogs.com/themoonforget/p/17973409