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

目录

一、高精度概念

二、高精度算法的实现

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不算前导0
	while (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时,会出现前导0
	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');

	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; //计算余数
	}
	//逆置:因为我们是正常求,但最后是倒着读的,且便于去除前导0
	reverse(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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

做接口自动化遇到的20个难点,记录下我是如何解决的!

我是一名接口自动化测试工程师&#xff0c;在公司中负责接口自动化测试的设计和执行。在公司中&#xff0c;接口自动化测试非常重要&#xff0c;因为公司的业务场景非常复杂&#xff0c;需要保证接口的质量。在这篇文章中&#xff0c;我将分享我在公司中接口自动化测试遇到的20…

代码随想录二刷 | 链表 |两两交换链表中的节点

代码随想录二刷 &#xff5c; 链表 &#xff5c;两两交换链表中的节点 题目描述解题思路 & 代码实现 题目描述 24.两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本…

中国出海主力系列专访之三七互娱:亚马逊云科技助力三七互娱海外“出圈”之路

如果问&#xff0c;在众多的中国出海赛道中哪一条拥有基数最大的粉丝拥趸&#xff1f;以网络游戏、社交媒体、直播、短视频为代表的泛娱乐赛道便成为当仁不让的领跑者。 在东京、新加坡、开罗、伦敦、纽约、慕尼黑等国际都市&#xff0c;当地的年轻人会随时随地的打开“中国造”…

同一台电脑访问gitee多个仓库代码

在开发上我们经常遇到&#xff0c;需要跟别人共享代码&#xff0c;特别是跟有些客户联合开发的情况下&#xff0c;有很多个客户。有些git仓库是客户建立的&#xff0c;比如有两个客户A和分布建了gitA和gitB两个代码仓库。我们在支持这两个客户的时候可能是同一个工程师&#xf…

OpenLayers实战,WebGL图层根据Feature要素的变量动态渲染多种颜色的三角形,适用于大量三角形渲染不同颜色

专栏目录: OpenLayers实战进阶专栏目录 前言 本章使用OpenLayers根据Feature要素的变量动态渲染不同颜色的三角形。 通过一个WebGL图层生成四种不同颜色的图形要素,适用于WebGL图层需要根据大量点要素区分颜色显示的需求。 更多的WebGL图层使用运算符动态生成样式的内容将会…

ubuntu 安装 gparted

前提环境&#xff1a; 阿里云的源。 sudo apt update sudo apt upgrade sudo apt install gparted 搜索&#xff1a;

RedisConnectionFactory is required已解决!!!!

1.起因&#x1f936;&#x1f936;&#x1f936;&#x1f936; redis搭建完成后&#xff0c;准备启动主程序&#xff0c;异常兴奋&#xff0c;结果报错了&#xff01;&#xff01;&#xff01;&#xff01; 2.究竟是何原因 &#x1f62d;&#x1f62d;&#x1f62d;&#x1f…

解决:ERR This instance has cluster support disabled

问题描述 在使用Redisson做分布式锁&#xff0c;连接redis时&#xff0c;提示以下错误&#xff1a; 问题定位 通过指令&#xff1a; cluster nodes查看&#xff0c;发现 出现这种提示的原因&#xff0c;是因为此Redis实例已经禁用了集群(默认状态下是禁用状态)。 解决 …

5.4 Windows驱动开发:内核通过PEB取进程参数

PEB结构(Process Envirorment Block Structure)其中文名是进程环境块信息&#xff0c;进程环境块内部包含了进程运行的详细参数信息&#xff0c;每一个进程在运行后都会存在一个特有的PEB结构&#xff0c;通过附加进程并遍历这段结构即可得到非常多的有用信息。 在应用层下&am…

②⑩ 【MySQL Log】详解MySQL日志:错误日志、二进制日志、查询日志、慢查询日志

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL日志 ②⑩ MySQL日志&#xff1a;错误日志…

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

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

对象分配规则

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

【shell】条件语句

一、测试 1.1文件测试test test命令是内部命令 test的语法 test 条件表达式 [ 条件表达式 ] test 选项 文件 -d &#xff1a;判断是否是目录 -f &#xff1a;判断是否是普通文件 -b &#xff1a;判断是否是块设备 -c &#xff1a;判断是否是字符设备 -e &#xff1a;判断是否…

autojs(意图篇之startActivity)

使用以下函数可以直接打开指定页面 app.startActivity({packageName:包名,className:活动页面类名,root:true })下面的问题是包名与类目如何获取&#xff1a; 打开所取页面运行如下代码&#xff1a; log("包名:"currentPackage()) log("活动页面类名&#xff1…

51单片机应用

目录 ​编辑 1. C51的数据类型 1.1 C51中的基本数据类型 1.2 特殊功能寄存器类型 2. C51的变量 2.1 存储种类 1. C51的数据类型 C51是一种基于8051架构的单片机&#xff0c;它支持以下基本数据类型&#xff1a; 位&#xff08;Bit&#xff09;&#xff1a;可以表…

Java 类之 java.util.Properties

Java 类之 java.util.Properties 文章目录 Java 类之 java.util.Properties一、简介二、主要功能1、存储键值对2、读取文件与属性代码示例运行结果截图 3、设置属性并保存文件代码示例结果截图 4、遍历属性代码示例运行结果 关联博客&#xff1a;《基于 Java 列举和说明常用的外…

全网最全最规范的测试用例的几种必学设计方法

例如&#xff0c;Dr. Genichi Taguchi 设计的正交表 https://www.york.ac.uk/depts/maths/tables/orthogonal.htm Technical Support ( support.sas.com ) com 提供的 http://support.sas.com/techsup/technote/ts723_Designs.txt 首先&#xff0c;我们来看看基本的概念。 因素…

利用python下的matplotlib库绘制能突出显示的饼状图

需求描述 根据已有的数据绘制一个占比图&#xff0c;期望能对其中的部分占比成分进行突出显示。 原始数据如下&#xff1a; 国外投资&#xff08;5%&#xff09;、公司投资&#xff08;8%&#xff09;、地方投资&#xff08;7%&#xff09;、中央财政&#xff08;80%&#xff…

【Python爬虫】8大模块md文档集合从0到scrapy高手,第7篇:selenium 数据提取详解

本文主要学习一下关于爬虫的相关前置知识和一些理论性的知识&#xff0c;通过本文我们能够知道什么是爬虫&#xff0c;都有那些分类&#xff0c;爬虫能干什么等&#xff0c;同时还会站在爬虫的角度复习一下http协议。 爬虫全套笔记地址&#xff1a; 请移步这里 共 8 章&#x…

笔尖笔帽检测3:Android实现笔尖笔帽检测算法(含源码 可是实时检测)

目录 1. 前言 2.笔尖笔帽检测方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下而上)方法&#xff1a; 3.笔尖笔帽关键点检测模型训练 4.笔尖笔帽关键点检测模型Android部署 &#xff08;1&#xff09; 将Pytorch模型转换ONNX模型 &#xff08;2&#xff09; 将ONNX模…