大整数运算

news/2025/1/15 18:34:43/文章来源:https://www.cnblogs.com/themoonforget/p/17973409

首先是遇到了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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/794382.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tarjan—算法的神(一)

本篇包含 tarjan 求强连通分量、边双连通分量、割点 部分, tarjan 求点双连通分量、桥(割边)在下一篇。伟大的 Robert Tarjan 创造了众多被人们所熟知的算法及数据结构,最著名的如:(本文的)连通性相关的 tarjan 算法,Splay-Tree,Toptree,tarjan 求 lca 等等。 注:有…

gitlab代码恢复

gitlab代码恢复背景: 从gitlab的web端页面下载了代码。需要恢复到新的gitlab上。下面操作以vonebaas-c-fabric-explorer-front工程为例 已经下载好vonebaas-c-fabric-explorer-front工程的zip包:操作步骤 原来的git地址是:http://xxx.git.com:9002/ 新的git地址是:http://1…

Vidful.ai:免费在线AI视频生成器

免费在线AI视频生成器Vidful.ai,无需下载或复杂操作,轻松将文字和图片转换为高质量、电影级视频!免费在线AI视频生成器Vidful.ai,无需下载或复杂操作,轻松将文字和图片转换为高质量、电影级视频! 网址:https://vidful.ai/ 为什么选择Vidful.ai?免费在线平台:无需下载、…

“数据守护,商业共赢” — 华企盾招商会议圆满落幕

在数字化浪潮席卷全球的今天,数据安全已成为企业可持续发展的基石。为了共同探讨数据防护的新策略,推动行业生态的健康发展,我司于2024年9月6日成功举办了一场以“数据守护,商业共赢”为主题的招商会议。此次会议汇聚了来自各行各业的精英人士,共同探讨如何有效应对数据安…

【优技教育】Oracle 19c OCP 082题库(第16题)- 2024年修正版

【优技教育】Oracle 19c OCP 082题库(Q 16题)- 2024年修正版 考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为(CUUG 原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。 原文地址:http://www.cuug.com/index.php?s=/home/article/deta…

Canvas绘制图片合成样式

效果图web * {margin: 0;padding: 0;}.container {position: relative;width: 328px;height: 328px;margin: 100px auto;}.container img {position: absolute;width: 328px;height: 328px;}#canvas {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);…

Axure的画图规范说明

Axure的画图规范说明自定义网页整体尺寸:1366x768;色值:# F8F9FD 顶部一级导航:1366x48;色值:# 1D8FFF 左右布局,左侧边导航:768x194;色值:# 191A23 侧边导航栏宽高:194x768 左侧一级菜单宽高:194x40/边距:16,字号:14,色值:#FFFFFF,图标:14x14,二级导航宽194w,…

解决vscode终端输出中文乱码问题图文教程

由于系统终端默认编码为GBK,所以需要修改为UTF-8 方法一 打开cmd输入chcp查看编码格式,查看以及修改如下图所示:方法二

Transformer、RNN和SSM的相似性探究:揭示看似不相关的LLM架构之间的联系

通过探索看似不相关的大语言模型(LLM)架构之间的潜在联系,我们可能为促进不同模型间的思想交流和提高整体效率开辟新的途径。 尽管Mamba等线性循环神经网络(RNN)和状态空间模型(SSM)近来备受关注,Transformer架构仍然是LLM的主要支柱。这种格局可能即将发生变化:像Jamba、Samba…