算法-----高精度算法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的长度是俩数中的最大值或+1for(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;
}

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

未完待续。。。。。。

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

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

相关文章

坚持刷题|环形链表

文章目录 题目考察点代码实现扩展问题 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;刷了一段时间二叉树啦&#xff0c;今天换链表刷&#xff1a;环形链表 题目 141. 环形链表 考察点 主要考察了链表的基本操作和快慢指…

PySQLRecon:一款功能强大的MSSQL安全测试工具

关于PySQLRecon PySQLRecon是一款功能强大的MSSQL安全测试工具&#xff0c;该工具基于SQLRecon实现其功能&#xff0c;可以帮助广大红队研究人员针对MSSQL执行攻击性安全测试。 环境配置 由于该工具基于Python 3开发&#xff0c;因此我们首先需要在本地设备上安装并配置好Pyt…

【51单片机】矩阵键盘(江科大)

6.1矩阵键盘 矩阵键盘&#xff1a; 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态 1.数码管扫描(输出扫描) 原理:显示第1位→显示第2位→显示第3位→ …… ,然后快速循环这个过程,最终实现所…

软件架构与系统架构:区别与联系的分析

软件架构与系统架构&#xff1a;区别与联系的分析 在信息技术领域&#xff0c;软件架构和系统架构这两个术语经常被提及。尽管它们在某些方面有重叠&#xff0c;但它们确实代表了不同的概念和聚焦点。理解这两种架构之间的区别和联系对于任何从事技术开发和设计的专业人士都是至…

【复现】Supabase后端服务 SQL注入漏洞_48

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 Supabase是什么 Supabase将自己定位为Firebase的开源替代品&#xff0c;提供了一套工具来帮助开发者构建web或移动应用程序。 Sup…

高效的工作学习方法

1.康奈尔笔记法 在这里插入图片描述 2. 5W2H法 3. 鱼骨图分析法 4.麦肯锡7步分析法 5.使用TODOLIST 6.使用计划模板&#xff08;年月周&#xff09; 7. 高效的学习方法 成年人的学习特点&#xff1a; 快速了解一个领域方法 沉浸式学习方法&#xff1a; 沉浸学习的判据&am…

TapableHookPlugins

以极客时间《玩转Webpack》课程学习为主的记录笔记。 源码解读 webpack的命令跟踪&#xff0c;从node_modules/webpack/bin/ 可以看到命令内容&#xff0c;webpack会查看是否下载安装了webpack-cli / webpack-command。使用webpack-cli 解析命令行信息、安装使用到的依赖&…

浅谈jmeter性能测试步骤入门

一、Jmeter简介 1 概述 jmeter是一个软件&#xff0c;使负载测试或业绩为导向的业务&#xff08;功能&#xff09;测试不同的协议或技术。 它是 Apache 软件基金会的Stefano Mazzocchi JMeter 最初开发的。 它主要对 Apache JServ&#xff08;现在称为如 Apache Tomca…

相机图像质量研究(12)常见问题总结:光学结构对成像的影响--炫光

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(3) 保存表格数据

对上两篇篇的工作C Qt框架开发| 基于Qt框架开发实时成绩显示排序系统&#xff08;1&#xff09;-CSDN博客和C Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统&#xff08;2&#xff09;折线图显示-CSDN博客继续优化&#xff0c;增加一个保存按钮&#xff0c;用于保存成绩数据…

WebSocket原理详解

目录 1.引言 1.1.使用HTTP不断轮询 1.2.长轮询 2.websocket 2.1.概述 2.2.websocket建立过程 2.3.抓包分析 2.4.websocket的消息格式 3.使用场景 4.总结 1.引言 平时我们打开网页&#xff0c;比如购物网站某宝。都是点一下列表商品&#xff0c;跳转一下网页就到了商品…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏17(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言制作木板UI直接复制和工具一样的即可检查背包是否有指定数量的空插槽 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇…