【算法之路】高精度算法(实现加减乘除)

目录

一、高精度概念

二、高精度算法的实现

1、高精度加法(大整数相加)

2、高精度减法(大整数减法)

3、高精度乘法(大整数*小整数)

4、高精度除法(大整数/小整数)


一、高精度概念

高精度算法,是一种处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几百亿的大数字。一般这类数字统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘等运算。对于非常庞大的数字无法在计算机中正常存储。于是,将这个数字拆开成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数

高精度就是说参与运算的数据和运算结果的范围,超出标准数据类型能表示的数据大小范围的运算。此时如果要得到正确的计算结果,就不能依靠普通方法实现了,而要在普通运算原理的基础上,加以辅助算法来实现超大数据的计算。
例如:求两个 500 位的数据相乘的结果,这时就要用到高精度算法了。


二、高精度算法的实现

1、高精度加法(大整数相加)

大整数又称为高精度整数,其含义就是用基本数据类型无法存储其精度的整数。 大整数的存储使用数组即可。

 

思路:

先将大整数倒序存储,然后从左往右相加,这样才算是从低位往高位加,并判断是否有进位,加出来的数取余后尾插到要保存的vector中,这样求出来的数还是逆序的,但是主函数会从后往前读

 AC代码:

#include<iostream>
#include<string>
#include<vector>
using namespace std;//1、高精度加法(大整数加法)
vector<int> add(vector<int>& A, vector<int>& B)
{//如果B更大,因为下面代码都是以第一个形参作为for结束条件,所以要让大的是第一个形参if (A.size() < B.size()) return add(B, A);vector<int> C;int t = 0; //用来判断是否进位//注意这里是逆序的数从前往后加的for (int i = 0; i < A.size(); ++i){//for循环是以大的数来作为循环结束条件的t += A[i];//for循环以A为结束条件,这里不用格外判断if (i < B.size()) t += B[i];//因没以B为结束条件,故这里要格外判断是否可以加C.push_back(t % 10);//加出来的数要的是余数t /= 10; //判断是否有进位}if (t) C.push_back(t);//有可能最后加完还有进位//第二种写法//这种写法不用格外判断最后是否有进位//for (int i = 0, t = 0; i < A.size()||t; ++i)//{//	if (i < A.size()) t += A[i];//因为有t作为条件,故这里要格外判断//	if (i < B.size()) t += B[i];//因没以B为结束条件,故这里要格外判断是否可以加//	C.push_back(t % 10);//加出来的数要的是余数//	t /= 10; //判断是否有进位//}return C;
}int main()
{string a, b;cin >> a >> b;vector<int> A, B;//把字符串逆序存入vector中,方便后续计算for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');auto C = add(A, B);for (int i = C.size() - 1; i >= 0; --i) cout << C[i];cout << endl;return 0;
}

2、高精度减法(大整数减法)

思路:

和加法区别在于其一,减法是要借位而不是进位,其二,减法会导致有前导0存在。

什么是前导0?比如124-113,我们存的是421,311,相减时是4-3=1,2-1=1,1-1=0,然后尾插导致C为110,我们最后是逆着读的,即011,(但正常124-113=11),这里011肯定不对,多了一个前导0,故我们最后要把这个前导0去掉变成11,然后逆着读出来就对了

AC代码: 

#include<iostream>
#include<string>
#include<vector>
using namespace std;//比较哪个数大,注意这里的数是从倒序存的,故后面的才是高位
bool cmp(vector<int>& A, vector<int>& B)
{if (A.size() != B.size()) return A.size() > B.size();for (int i = A.size() - 1; i >= 0; --i)if (A[i] != B[i]) return A[i] > B[i];//不等从高位开始比return true;//相等
}vector<int> sub(vector<int>& A, vector<int>& B)
{//利用cmp函数比较,使大的数一定是A,与for循环代码相符vector<int> C;int t = 0;//判断借位for (int i = 0; i < A.size(); ++i){t = A[i] - t;//每次都会减掉借位if (i < B.size()) t -= B[i];//关于(t+10)%10(t是减出来的数)//t若为正数(但<=9)其=t%10+10%10=t//t若为负数,正好可以借位+10然后取余数即可C.push_back((t + 10) % 10);if (t >= 0) t = 0;else t = 1; //<0肯定有借位了}//因为两个数相减会导致有多余的0出现,故去除前导0//size()>1是因为可能真的相减出现0,这种0不算前导0while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}int main()
{string a, b;cin >> a >> b;vector<int> A, B;//把字符串逆序存入vector中,方便后续计算for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');vector<int> C;if (cmp(A, B)) C = sub(A, B); //正数else cout << "-", C = sub(B, A); //负数for (int i = C.size() - 1; i >= 0; --i) cout << C[i];cout << endl;return 0;
}

3、高精度乘法(大整数*小整数)

思路: 

AC代码: 

#include<iostream>
#include<string>
#include<vector>
using namespace std;vector<int> mul(vector<int>& A, int b)
{vector<int> C;for (int i = 0, t = 0; i < A.size() || t; ++i){if (i < A.size()) t += A[i] * b;//加上t是因为上一次可能有乘出来的进位C.push_back(t % 10);t /= 10;//计算进位}//当b是0时,会出现前导0while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}int main()
{string a;int b;cin >> a >> b;vector<int> A;for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');auto C = mul(A, b);for (int i = C.size() - 1; i >= 0; --i) cout << C[i];cout << endl;return 0;
}

4、高精度除法(大整数/小整数)

思路:

 

AC代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;vector<int> div(vector<int>& A, int b, int& r)
{vector<int> C;for (int i = A.size() - 1; i >= 0; --i){r = r * 10 + A[i];C.push_back(r / b);r %= b; //计算余数}//逆置:因为我们是正常求,但最后是倒着读的,且便于去除前导0reverse(C.begin(), C.end());while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}int main()
{string a;int b;cin >> a >> b;vector<int> A;for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');int r = 0; //余数auto C = div(A, b, r);for (int i = C.size() - 1; i >= 0; --i) cout << C[i];cout << endl << r << endl;return 0;
}

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

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

相关文章

Java GUI实现桌球小游戏

桌球游戏是一种室内运动&#xff0c;通常在一个正式的桌球台上进行。这种游戏也被称为台球或母球。桌球游戏的目标是使用一个击球杆将彩球击入桌面四个角落的袋子中&#xff0c;得分最高的一方获胜。桌球游戏需要一定的技巧和策略&#xff0c;因此是一项受欢迎的竞技运动和休闲…

生成对抗网络Generative Adversarial Network,GAN

Basic Idea of GAN Generation&#xff08;生成器&#xff09;  Generation是一个neural network&#xff0c;它的输入是一个vector&#xff0c;它的输出是一个更高维的vector&#xff0c;以图片生成为例&#xff0c;输出就是一张图片&#xff0c;其中每个维度的值代表生…

前端环境变量释义

视频教程 彻底搞懂前端环境变量使用和原理&#xff0c;超清楚_哔哩哔哩_bilibili 添加命令行参数 --modexxxxx 新建.env.xxxx文件,其中.env文件会在所有环境下生效 以VITE_开头&#xff0c;字符串无需加双引号 使用import.meta.env.VITE_xxxxx进行调用

React中封装echarts图表组件以及自适应窗口变化

文章目录 前言环境代码接口使用效果后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;react.js &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0c;…

很多人都在用的现货白银突破交易法 缺点需要注意

突破交易是现货白银投资者常用的交易技巧。通常做突破交易有两种方法&#xff0c;一种是突破发生的时候马上入场&#xff0c;另一种是在突破确认后等待回调然后再入场。目前&#xff0c;投资者较多的是使用后者。用突破——回踩入场有什么优缺点呢&#xff1f;下面我们就来讨论…

Java(四)(多态,final,常量,抽象类,接口)

目录 多态 基本概念: 使用多态的好处 类型转换 遇到的问题 解决方法 强制类型转换的一个注意事项 final 常量 抽象类 啥是个抽象类? 抽象类的注意事项,特点 抽象类的场景和好处 抽象类的常见应用场景: 模板方法设计模式 接口 基本概念 接口的好处 JDK8开始,接…

[计算机网络实验]头歌 实验二 以太网帧、IP报文分析

第1关&#xff1a;Wireshark基本使用入门 【实验目的】 1、掌握wireshark工具的基本使用方法 【实验环境】 1、头歌基于Linux的虚拟机桌面系统 2、网络报文分析工具wireshark 3、浏览器firefox 【本地主机、平台虚拟机之间数据传递】 1、文本的复制与粘贴 操作入口&…

半导体业库存问题缓解,明年迎来良好转机 | 百能云芯

随着全球半导体产业今年产值预计将出现逾1成的衰退&#xff0c;市场一度陷入不确定性。然而&#xff0c;半导体厂商们对于供应链库存的有效去化表示乐观&#xff0c;预计将为明年带来健康的复苏。在各种因素交织的复杂情况下&#xff0c;半导体产业展现出逐步解决库存问题、迎来…

vivado产生报告阅读分析14-时序报告10

Vivado IDE 中的例外报告 “ Report Exceptions ”对话框 在 AMD Vivado ™ IDE 中 &#xff0c; 选择“ Reports ” → “ Timing ” → “ Report Exceptions ” &#xff08; 报告 > 时序 > 例外报告 &#xff09; 即可打开“Report Exceptions ”对话框。 从“…

第三届VECCTF-2023 Web方向部分wp

拳拳组合 题目描述&#xff1a;明喜欢保存密钥在某个文件上。请找到秘钥并读取flag文件。 开题&#xff0c;点不完的。源码提示&#xff1a; <!--据说小明很喜欢10的幂次方--> 扫一下看看&#xff0c;应该是有git泄露。 其它一些路由没什么用 git泄露拿下一堆码 pytho…

给卖家的 5 个 TikTok 联盟营销创意

了解如何开始 TikTok 联盟营销不足以让您为 TikTok 商店实施最佳联盟计划。促进您的 TikTok 联盟营销工作。如下&#xff1a; 建立相关受众 为了确保您在 TikTok 联盟营销上的投资没有白费&#xff0c;清楚地了解您的目标受众至关重要。只有了解了这个平台的目标受众&#xf…

最全面的SHEIN开店流程,手把手教你从零起步,轻松开店!

SHEIN作为一家全球性的时尚电商平台&#xff0c;为年轻人提供了更多时尚选择和机会&#xff0c;同时也吸引了众多跨境电商卖家的关注。在5月份&#xff0c;SHEIN推出了第三方卖家平台&#xff0c;为卖家提供了全新的商机和发展赛道。毕竟目前SHEIN平台的流量是非常大的&#xf…

第2章 传输网

文章目录 2.1 传输网概述2.2 SDH传输网2.2.2 SDH的基本网络单元1、终端复用器&#xff08;TM&#xff09;2、分插复用器&#xff08;ADM&#xff09;3、再生中继器&#xff08;REG&#xff09;4、数字交叉连接设备&#xff08;DXC设备&#xff09; 2.2.3 SDH的帧结构2.2.4 …

VSCode新建Vue项目

前言 Vue.js 是一款流行的 JavaScript 前端框架&#xff0c;它可以帮助开发者轻松构建高性能、可扩展的 Web 应用程序。而 VSCode 则是一款功能强大的开源代码编辑器&#xff0c;它提供了许多有用的工具和插件&#xff0c;可以大幅提高开发效率。 在本文中&#xff0c;我们将…

UE4 基础篇十四:自定义插件

文末有视频地址和git地址 一、概念 虚幻里插件都是用C++写的,C++包括.h文件和.cpp文件,.h头文件通常包含函数类型和函数声明,cpp文件包含这些类型和函数的实现, 你为项目编写的所有代码文件都必须位于模块中,模块就是硬盘里的一个文件夹,包含名为“Build.cs”的C#文件…

vue实现el-menu与el-tabs联动

效果图如下&#xff1a; 当标签栏很多的时候效果图如下&#xff1a; 左侧菜单布局 &#xff08;$route.path高亮显示激活路由 :default-active"$route.path"&#xff09; <el-menu:default-active"$route.path"class"el-menu-vertical-demo"b…

PaaS、 IaaS 和 SaaS 的区别

我感觉我有点捂了 iaas&#xff0c;paas&#xff0c;和saas的区别&#xff0c;以及他们啥意思了 简单说就是&#xff0c;一个公司有很多项目&#xff0c;要管理这些项目&#xff0c;每个项目都有很多组成部分需要管理的地方&#xff0c;例如&#xff0c;存储代码&#xff0c;例…

掌握5个关键点,搞定语音识别测试!

现在市面上的智能电子产品千千万&#xff0c;为了达到人们使用更加方便的目的&#xff0c;很多智能产品都开发了语音识别功能&#xff0c;用来语音唤醒进行交互&#xff1b; 另外&#xff0c;各大公司也开发出来了各种智能语音机器人&#xff0c;比如小米公司的“小爱”&#…

UE5 操作WebSocket

插件&#xff1a;https://www.unrealengine.com/marketplace/zh-CN/product/websocket-client 参考&#xff1a;http://dascad.net/html/websocket/bp_index.html 1. 安装Plugings 2.测试websocket服务器 http://www.websocket-test.com/ 3.连接服务器 如果在Level BP里使用&a…