算法-----高精度算法1(高精度加法,高精度减法)(详解)

什么是高精度算法?

高精度的意思就是他得名字----高的精度,简单说就是位数很大,而高精度算法就是将这些高精度数(位数很大在几百几千几万位的数叫高精度数)通过计算机的型式模拟出来结果。

为什么要用高精度算法?

在这里插入图片描述

我们都知道c++中int的最大值是2^31,unsigned int的最大值是2的32次方,最大的unsigned long long可以到18446744073709551615 。double是浮点型的最大类型,他的最大值是1.7 * 10^308。
这些数据类型对于1+1=2或43545*51345=2235818025这些式子来说绰绰有余,但如果是下面的呢----
153169256934561745635416456903465967693845681963457348+13547477864672672675474676754676783587875372274=? 265464562574318759893457913479346x6524632656224562664=?
3466779657942964574257456/432654724567=?..?
这些式子的数和结果都非常大long long 和 double 都存不下,这时就是要用高精度来计算了

高精度加法

1168:大整数加法
P1601 A+B Problem(高精)
因为不能用计算机直接计算,只能靠模拟。
让我们回顾一下小学一年级时学的加法。

在这里插入图片描述
通过这个竖式我们想想是否可以把高精度加法转换成一道让我们模拟加法竖式的模拟题呢?答案是肯定的
带着这个假想我们可以尝试下
首先初始化
注意!!!:因为位数较大所以我们要用字符串或字符数组

const int N=205;    //定义大小 
string s1,s2;    //俩数 
int a[N],b[N],c[N];   //存放俩数及结果数组 

好了第二步-------读入(read)

void read(){
	cin>>s1>>s2;
} 

好读入结束,等下,这么草草就结束了a,b数组怎么办。
所以为了照顾a,b数组,我们需要把俩字符串数转成整数数组的型式。
但真的是顺着存储吗?不对
如果顺着存储就是这样
在这里插入图片描述
本来1257+934的式子竟然变了!而且当你好不容易把他变回去时就会发现如果进位时如123+930数组下标竟然需要负数才能存下那个进位的1了!所以顺着存不行,那试试逆序存呢?
大家可以在草稿纸上试试可以发现,逆着存是可以的,也防止了进位溢出的情况
所以,对于存储s1,s2俩数,应用整数数组逆着存。

void read(){
	cin>>s1>>s2;
	int len1=s1.size(),len2=s2.size();
	for(int i=0;i<len1;i++) a[i]=(s1[len1-i-1]-'0');  //逆序存储。需要字符转整数
	for(int j=0;j<len2;j++) b[j]=(s2[len2-j-1]-'0');
} 

好的终于到模拟部分了
让我们先考虑一下重点
1.考虑进位
2.考虑该进位多少
3.最重要的一点。前导零该怎么办
4.最高位进位
好的一步步来
第一点。因为单个位最大是9,俩9相加才18,进位不可能超1,所以第一部分和第二部分可以同时考虑。如果结果大于10,我们可以将结果-10,或直接不判断直接%10,当然我们也要考虑到当前的i+1位也要+1,所以我们可以用变量来表示这种情况。第三点我们可以从尾开始遍历碰到0就舍去(len-1).如果没碰到就break。第四点我们可以用变量储存模拟完毕后特判下
好分析完毕,代码如下

void count(){
	int jw=0;
	len=max(s1.size(),s2.size());   //c的长度是俩数中的最大值或+1
	for(int i=0;i<len;i++){
		c[i]=a[i]+b[i]+jw;    //求当前结果
		jw=c[i]/10;        //进位数
		c[i]%=10;    //得出当前数
	} 
	if(jw==1){   //处理最高位进位
	len++;
	c[len-1]=1;
	}
	while(c[len-1]==0) len--;    //去前导零
}

等下考虑下0+0的结果 ,是空,不是0吗,原来当len==1时就算是0也不能舍去
修改如下

void count(){
	int jw=0;
	len=max(s1.size(),s2.size());
	for(int i=0;i<len;i++){
		c[i]=a[i]+b[i]+jw;
		jw=c[i]/10;
		c[i]%=10;
	} 
	if(jw==1){
	len++;
	c[len-1]=1;
	}
	while(len>1&&c[len-1]==0) len--;
}

最后到输出部分了,应为开始时是逆序存所以也要逆序输出正所谓负负得正

void print(){
	for(int i=len-1;i>=0;i--) cout<<c[i];
}

最后总代如下

#include<bits/stdc++.h>
using namespace std;
const int N=205;     
string s1,s2;  
int a[N],b[N],c[N];  
int len;
void read(){ //读入
	cin>>s1>>s2;
	int len1=s1.size(),len2=s2.size();
	for(int i=0;i<len1;i++) a[i]=(s1[len1-i-1]-'0');
	for(int j=0;j<len2;j++) b[j]=(s2[len2-j-1]-'0');
} 
void count(){    //模拟竖式
	int jw=0;
	len=max(s1.size(),s2.size());
	for(int i=0;i<len;i++){
		c[i]=a[i]+b[i]+jw;
		jw=c[i]/10;
		c[i]%=10;
	} 
	if(jw==1){
		len++;
		c[len-1]=1;
	}
	while(len>1&&c[len-1]==0) len--;
}
void print(){  //输出
	for(int i=len-1;i>=0;i--) cout<<c[i];
}
int main(){
read();
count();
print();
   return 0;
}

另外用结构体来计算大整数加法也是常见的,这里不做多说明了与上文类似

#include<bits/stdc++.h>
using namespace std;
string str;
struct node{   //定义
	int len,s[205];
	node(){len=0;memset(s,0,sizeof(s));}
};
node a,b,c;
node operator + (const node&a,const node&b){  //重载加法运算符
	node c;
	c.len=max(a.len,b.len);
	for(int i=1;i<=c.len;i++){
		c.s[i]+=a.s[i]+b.s[i];
		c.s[i+1]+=c.s[i]/10;
		c.s[i]%=10;
	}
	if(c.s[c.len+1]) c.len++;
	return c;
}
node read(){   //读入加去前导零
	cin>>str;
	int len=str.size();
    node a;a.len=len;
    for(int i=0;i<len;i++){
    	a.s[len-i]=str[i]-'0';
	}
	while(a.len>1&&a.s[a.len]==0) a.len--;
	return a;
}

void print(node a){//输出
	for(int i=a.len;i>=1;i--) cout<<a.s[i];
}
int main(){

a=read(),b=read();
c=a+b;
print(c);
   return 0;
}

高精度减法

1169:大整数减法
与高精度加法类似也是模拟
初始化+读入

string s1,s2;
int a[205],b[205],c[205];
int len;
void read(){
	cin>>s1>>s2;
	int n=s1.size(),m=s2.size();
	len=max(n,m);
	for(int i=0;i<n;i++){
		a[i]=s1[n-i-1]-'0';
	}
	for(int j=0;j<m;j++){
		b[j]=s2[m-j-1]-'0';
	}
}

模拟竖式。
这里也有两项需考虑
1.借位
2.去前导零
第二步相信你们很轻松就能解决。而第一步也很简单我们正常减,如果c[i]<0,那么需要借位了有加就有减,所以c[i]+=10;c[i+1]–;
代码如下

void less(){
	for(int i=0;i<len;i++){
		c[i]+=a[i]-b[i];
		if(c[i]<0){
			c[i]+=10;
			c[i+1]--;
		}
	}
	while(len>1&&c[len-1]==0) len--;
}

最后逆序输出

void print(){
	for(int i=len-1;i>=0;i--) cout<<c[i];
}

总代码

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[205],b[205],c[205];
int len;
void read(){
	cin>>s1>>s2;
	int n=s1.size(),m=s2.size();
	len=max(n,m);
	for(int i=0;i<n;i++){
		a[i]=s1[n-i-1]-'0';
	}
	for(int j=0;j<m;j++){
		b[j]=s2[m-j-1]-'0';
	}
}
void lss(){
	for(int i=0;i<len;i++){
		c[i]+=a[i]-b[i];
		if(c[i]<0){
			c[i]+=10;
			c[i+1]--;
		}
	}
	while(len>1&&c[len-1]==0) len--;
}
void print(){
	for(int i=len-1;i>=0;i--) cout<<c[i];
}
int main(){
read();
lss();
print();
   return 0;
}

这边结构体减法代码就不放了,有兴趣可以自己做下。
总结下来,只要会高精度加法就会高精度减法。

未完待续。。。。。。

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

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

相关文章

《Java 简易速速上手小册》第5章:Java 开发工具和框架(2024 最新版)

文章目录 5.1 Maven 和 Gradle - 构建你的堡垒5.1.1 基础知识5.1.2 重点案例&#xff1a;使用 Maven 构建一个简单的 Java 应用5.1.3 拓展案例 1&#xff1a;使用 Gradle 构建一个 Spring Boot 应用5.1.4 拓展案例 2&#xff1a;使用 Maven 管理多模块项目 5.2 Spring 框架 - 你…

CSS介绍

本章目标&#xff1a; CSS概述 三种样式表 简单选择器 复合选择器 盒子模型 常用背景样式 浮动 常用文本样式 伪类样式 列表样式 表格样式 定位 一、CSS概述: CSS&#xff1a;cascading style sheets-层叠样式表 专门负责对网页的美化 二、有三种使用方式&…

JavaScript中的常见算法

一.排序算法 1.冒泡排序 冒泡排序比较所有相邻的两个项&#xff0c;如果第一个比第二个大&#xff0c;则交换它们。元素项向上移动至 正确的顺序&#xff0c;就好像气泡升至表面一样。 function bubbleSort(arr) {const { length } arrfor (let i 0; i < length - 1; i)…

leetcode:55.跳跃游戏

1.解题思路&#xff1a;贪心算法看最大覆盖范围 2.模拟过程&#xff1a; 1.若数组长度等于1&#xff0c;直接返回True 2.循环遍历覆盖范围&#xff0c;选取最大的覆盖范围&#xff1b;若覆盖范围覆盖到了最后一个元素&#xff0c;直接返回true. 3.代码&#xff1a;(贪心无套…

【医学大模型 知识增强】SMedBERT:结构化语义知识 + 医学大模型 = 显著提升大模型医学文本挖掘性能

SMedBERT&#xff1a;结构化语义知识 医学大模型 显著提升医学文本挖掘任务性能 名词解释结构化语义知识预训练语言模型医学文本挖掘任务 提出背景具体步骤提及-邻居混合注意力机制实体嵌入增强实体描述增强三元组句子增强 提及-邻居上下文建模域内词汇权重学习领域自监督任务…

Servlet JSP-Eclipse安装配置Maven插件

Maven 是一款比较常用的 Java 开发拓展包&#xff0c;它相当于一个全自动 jar 包管理器&#xff0c;会导入用户开发时需要使用的相应 jar 包。使用 Maven 开发 Java 程序&#xff0c;可以极大提升开发者的开发效率。下面我就跟大家介绍一下如何在 Eclipse 里安装和配置 Maven 插…

基于STM32与FreeRTOS的四轴机械臂项目

目录 一、项目介绍 二、前期准备 1.硬件准备 2.开发环境 3.CubeMX配置 三、裸机各种模块测试 1.舵机模块 2.蓝牙模块 3.按键摇杆传感器模块和旋钮电位器模块 4.OLED模块 5.W25Q128模块 四、裸机三种控制测试 1.摇杆控制 2.示教器控制 3.蓝牙控制 五、裸机与Free…

MATLAB 1:基础知识

MATLAB中的数据类型主要包括数值类型、逻辑类型、字符串、函数句柄、结构体和单元数组类型。这六种基本的数据类型都是按照数组形式存储和操作的。 MATLAB中还有两种用于高级交叉编程的数据类型&#xff0c;分别是用户自定义的面向对象的用户类类型和Java类类型。 1.1.1数值类…

python算法之 Dijkstra 算法

文章目录 基本思想&#xff1a;步骤&#xff1a;复杂度&#xff1a;注意事项&#xff1a;代码实现K 站中转内最便宜的航班 Dijkstra 算法是一种用于解决单源最短路径问题的经典算法。该问题的目标是找到从图中的一个固定顶点&#xff08;称为源点&#xff09;到图中所有其他顶点…

Linux_进程概念

硬件系统 软件系统 进程概念 进程状态 孤儿进程 进程优先级 一.硬件系统 1.1 冯诺依曼体系结构 数学家冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#xff08;运算器、控制器、存储器、输入设备、输出设备&a…

例39:使用List控件

建立一个EXE工程&#xff0c;在窗体上放一个文本框&#xff0c;一个列表框和三个按钮输入如下的代码&#xff1a; Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)List1.AddItem(Text1.Text)End SubSub Form1_Command2_BN_Clicked(hWndForm As hWnd, h…

【教程】C++语言基础学习笔记(七)——Array数组

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

服务流控(Sentinel)

引入依赖 <!-- 必须的 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><!-- sentinel 核心库 --> <dependency><groupId>com.ali…

Rust入门:如何在windows + vscode中关闭程序codelldb.exe

在windows中用vscode单步调试rust程序的时候&#xff0c;发现无论是按下stop键&#xff0c;还是运行完程序&#xff0c;调试器codelldb.exe一直霸占着主程序不退出&#xff0c;如果此时对代码进行修改&#xff0c;后续就没法再编译调试了。 目前我也不知道要怎么处理这个事&am…

npm报错之package-lock.json found. 问题和淘宝镜像源过期问题

1、package-lock.json found. 问题的解决 在执行yarn add react-transition-group -S 安装react-transition-group时出现package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in orde…

Gitee的使用教程(简单详细)

1.安装git&#xff08;我的电脑自带git&#xff0c;我没弄这步QAQ&#xff09; Git (git-scm.com)https://git-scm.com/ 安装好后在桌面点击鼠标右键会出现git GUI 和 git Bash&#xff08;没有的话点击显示更多选项&#xff09; 2.去gitee上注册一个账号 工作台 - Gitee.co…

Hive的Join连接

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

耳机壳UV树脂制作私模定制耳塞适合什么样的人使用呢?

耳机壳UV树脂制作私模定制耳塞适合以下人群使用&#xff1a; 对音质要求高的人&#xff1a;私模定制耳塞能够完美契合用户的耳朵形状&#xff0c;减少漏音和外部噪音的干扰&#xff0c;提供更好的音质体验。需要长时间佩戴耳机的人&#xff1a;私模定制耳塞能够提高佩戴舒适度…

【Django】Django内建用户系统

Django内建用户系统 14.1 Django中的用户认证 Django带有一个用户认证系统系统&#xff0c;它处理用户用户账号、组、权限以及基于cookie的用户会话。 用户可以直接使用Django自带的用户表。 官方文档&#xff1a;https://docs.djangoproject.com/zh-hans/2.2/topics/auth/ …

C语言—基础数据类型(含进制转换)

进制转换不多&#xff0c;但我觉得适合小白(我爱夸自己嘿嘿) 练习 1. 确认基础类型所占用的内存空间(提示&#xff1a;使用sizeof 运算符)&#xff1a; 在这里我说一下&#xff0c;long 类型通常占用 4 字节。在 64 位系统上&#xff0c;long 类型通常也可为 8 字节。 格式…