【算法思想】高精度

引入

首先了解:
1. int 范围为10^9
2. long long 范围数量级为10^18

如果超过该数量级,该怎么办?
——这就是高精度、大数的算法问题

加法

输入两个整数a,b,输出他们的和(<=10的500次方)

核心是加法的核心——》每个数的结果等于这个位置的a,b加上上一个位置的进位c

c[i]+=a[i]+b[i];//+=的原因是,它要加上上一位的进位,上一位的进位早已存储在c[i]里面了
c[i+1]=c[i]/10;//算出进位的数字
c[i]%=10;//这个位置的数字


算法核心代码给出来了,下面就是要实践了。

题目


https://www.luogu.com.cn/problem/P1601
 ——就是这个题目(输入两个整数a,b,输出他们的和(<=10的500次方)
 

 #include<bits/stdc++.h>using namespace std;char s1[1000],s2[1000];
int a[1000],b[1000],c[1000];int main()
{scanf("%s",s1);//数组本身代表地址,不用加&scanf("%s",s2);int m=strlen(s1);int n=strlen(s2);//确定长度以确保可以把所有字母转化为数字for(int i=0;i<m;i++){a[m-i-1]=s1[i]-'0';//假设输入123,3应该是最先计算的,但它位于最后一位,a和b的位数不一定一样,所以要倒置数组}for(int i=0;i<n;i++){b[n-i-1]=s2[i]-'0';}m=max(m,n)+1;//+1是为了以防进位for(int i=0;i<m;i++){c[i]+=a[i]+b[i];c[i+1]=c[i]/10;c[i]%=10;}//由于可能出现输出的最高位为0,也就是c[m],但也有输出结果为0的情况,所以需要进行修改n=m-1;if(c[n]==0&&m>0){m--;//最大值减1}for(int i=m-1;i>=0;i--)//?{printf("%d",c[i]);}return 0;
}


另一种写法为:
 

#include<bits/stdc++.h>using namespace std;char s1[1000],s2[1000];
int a[1000],b[1000],c[1000];int main()
{scanf("%s",s1);//数组本身代表地址,不用加&scanf("%s",s2);int m=strlen(s1);int n=strlen(s2);//确定长度以确保可以把所有字母转化为数字for(int i=0;i<m;i++){a[m-i]=s1[i]-'0';//假设输入123,3应该是最先计算的,但它位于最后一位,a和b的位数不一定一样,所以要倒置数组}for(int i=0;i<n;i++){b[n-i]=s2[i]-'0';}m=max(m,n)+1;//+1是为了以防进位for(int i=1;i<=m;i++){c[i]+=a[i]+b[i];c[i+1]=c[i]/10;c[i]%=10;}//由于可能出现输出的最高位为0,也就是c[m],但也有输出结果为0的情况,所以需要进行修改if(c[m]==0&&m>0){m--;//最大值减1}for(int i=m;i>0;i--)//?{printf("%d",c[i]);}return 0;
}


他们的区别在于,在倒置数组时,一个让数组a,b从0开始,一个让数组从1开始计算。

Tips
1. 做加法时,由于要每一位的数字,所以为了简便,先都输入到char数组中,再转化为数字
2. 转化成数字的时候,记得要倒置数组——》加法计算从最低位计算,所以要把本身最后存进去的数字放到第一次计算的位置
3. 记得要更新c(也就是答案数组)的长度
4. 记得最后判断c的最高位为0且其长度不为0(不是0+0=0这种情况)时,不要输出这个最高位.
5. 最后输出要从最高位输出


减法

依旧是高精度题目
先随便列一个减号方程,一位一位的减
然后我们观察到一下规律:
        1. 如果a[i]>b[i]则直接相减出结果即可
        2. 如果a[i]<b[i],需要借位
            a[i+1]--;
            答案等于a[i]-b[i]+10;

根据规律,我们可以写出代码:

if(a[i]>b[i]){c[i]-=b[i];
}else
{c[i]=a[i]-b[i]+10;a[i+1]--;
}


但是需要注意一点——a一定要比b大,不然整体输出会是负数,如果不是,可以把a和b进行交换。
除了这个部分,其它都和加法没什么区别

题目:


https://www.luogu.com.cn/problem/P2142

模板题代码:

#include<bits/stdc++.h>
using namespace std;char s1[10090], s2[10090], s3[10090];
int a[10090], b[10090], c[10090];bool compare(char *s1, char *s2) {int len1 = strlen(s1);int len2 = strlen(s2);if (len1 != len2) return len1 > len2; // 如果长度不同,长的数更大for (int i = 0; i < len1; i++) {if (s1[i] != s2[i]) return s1[i] > s2[i]; // 按位比较}return true; // 如果完全相同,返回true
}int main() {scanf("%s", s1);scanf("%s", s2);if (!compare(s1, s2)) { // 如果s2比较大cout << "-";strcpy(s3, s1);strcpy(s1, s2);strcpy(s2, s3);}int m = strlen(s1);int n = strlen(s2);for (int i = 0; i < m; i++) {a[m - i] = s1[i] - '0';}for (int i = 0; i < n; i++) {b[n - i] = s2[i] - '0';}m = max(m, n);for (int i = 1; i <= m; i++) {if (a[i] < b[i]) {a[i + 1]--;a[i] += 10 ;} c[i] = a[i] - b[i];}while (m > 1 && c[m] == 0) m--; // 去除前导零for (int i = m; i > 0; i--) {printf("%d", c[i]);}return 0;
}

乘法

还是分析如果要一步步得去计算a乘b。
从中得出规律
        1. 乘数从最低位开始取,没取一位都要和被乘数相乘,也就是被乘数的每一位乘以这位数字。
        2. 假如乘以这位数字结果大于10,则需要进位,10位数进位,个位数留下
        3. 把最后的结果错位相加即可

我们可以用字母来替代数字从而观察如何错位相加——例如a4a3a2a1乘b3b2b1
通过计算,我们可以发现,假如结果存储在c数组中,那么aibj对应的是ci+j-1的位置

得出代码:

c[i+j-1]+=a[i]*b[j];
c[i+j]+=c[i+j-1]/10;//算出要进位的数字,这个用+=是因为c[i+j-1]通常不止一个
c[i+j-1]%=10;//算出留下来的这一位


题目:

https://www.luogu.com.cn/problem/P1303

代码:

#include<bits/stdc++.h>using namespace std;char s1[2009],s2[2009];
int a[2009],b[2009],c[4009];int main()
{scanf("%s",s1);scanf("%s",s2);int la=strlen(s1);int lb=strlen(s2);for(int i=0;i<la;i++){a[la-i]=s1[i]-'0';}for(int i=0;i<lb;i++){b[lb-i]=s2[i]-'0';}int lc=la+lb;for(int i=1;i<=la;i++){for(int j=1;j<=lb;j++){c[i+j-1]+=a[i]*b[j];c[i+j]+=c[i+j-1]/10;c[i+j-1]%=10;}}while(c[lc]==0&&lc>1){lc--;}for(int i=lc;i>0;i--){printf("%d",c[i]);}return 0;
}

总结

根据题目和代码,我们知晓了如何利用简单方法来计算高精度的题目,还需要注意的是创建数组的大小时,往往设置为设置精度的次方数
例如如果说明数范围为10的10086次方,那么如果是加减法那么所有的数组大小都为【10090】//多一点保险
如果是乘法,那么需要让c数组,也就是存储结果的数组=2倍的【10090】

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

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

相关文章

【失败了】LazyGraphRAG利用本地ollama提供Embedding model服务和火山引擎的deepseek API构建本地知识库

LazyGraphRAG测试结果如下 数据&#xff1a; curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt -o ./ragtest/input/book.txt 失败了 气死我也&#xff01;&#xff01;&#xff01;对deepseek-V3也不是很友好啊&#xff0c;我没钱prompt 微调啊&#xff0c;晕死…

ccfcsp3402矩阵重塑(其二)

//矩阵重塑&#xff08;其二&#xff09; #include<iostream> using namespace std; int main(){int n,m,t;cin>>n>>m>>t;int c[10000][10000];int s0,sum0;int d[10000],k[100000];for(int i0;i<n;i){for(int j0;j<m;j){cin>>c[i][j];d[s…

算法-除自身以外数组的乘积

力扣题目&#xff1a;238. 除自身以外数组的乘积 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums…

Unity Shader - UI Sprite Shader之简单抠图效果

Sprite抠图效果&#xff1a; 前言 在PhotoShop中我们经常会用到抠图操作&#xff0c;现在就用Shader实现一个简单的抠图效果。 实现原理&#xff1a; 使用当前像素颜色与需要抠掉的颜色相减作比较&#xff0c;然后与一个指定的阈值比较以决定是否将其显示出来&#xff1b; U…

【Mac】安装 Parallels Desktop、Windows、Rocky Linux

一、安装PD 理论上&#xff0c;PD只支持试用15天&#xff01;当然&#xff0c;你懂的。 第一步&#xff0c;在 Parallels Desktop for Mac 官网 下载 Install Parallels Desktop.dmg第二步&#xff0c;双击 Install Parallels Desktop.dmg 第三步&#xff0c;双击安装Paralle…

学习单片机需要多长时间才能进行简单的项目开发?

之前有老铁问我&#xff0c;学单片机到底要多久&#xff0c;才能进行简单的项目开发&#xff1f;是三个月速成&#xff0c;还是三年磨一剑&#xff1f; 今天咱们就来聊聊这个话题&#xff0c;我不是什么高高在上的专家&#xff0c;就是个踩过无数坑、烧过几块板子的“技术老友”…

pyqt 上传文件或者文件夹打包压缩文件并添加密码并将密码和目标文件信息保存在json文件

一、完整代码实现 import sys import os import json import pyzipper from datetime import datetime from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,QPushButton, QLineEdit, QLabel, QFileDialog,QMessageBox, QProgressBar) from PyQt5.…

centos操作系统上传和下载百度网盘内容

探序基因 整理 进入百度网盘官网百度网盘 客户端下载 下载linux的rpm格式的安装包 在linux命令行中输入&#xff1a;rpm -ivh baidunetdisk_4.17.7_x86_64.rpm 出现报错&#xff1a; 错误&#xff1a;依赖检测失败&#xff1a; libXScrnSaver 被 baidunetdisk-4.17.7-1.x8…

LeetCode134☞加油站

关联LeetCode题号134 本题特点 贪心局部最优解-部分差值 如果小于0&#xff08;消耗大于油站油量&#xff09; 就从下一个加油站开始&#xff0c;因为如果中间有小于0的情况 当前站就不可能是始发站&#xff0c;整体最优解-整体差值 如果小于0 &#xff0c;那么就是不能有始发…

基于 Verilog 的时序设计:从理论到实践的深度探索

在数字电路设计领域,时序设计是一个至关重要的环节,它涉及到组合逻辑电路与时序逻辑电路的设计差异、时钟信号的运用以及触发器的工作原理等多个方面。本文将围绕基于 Verilog 的时序设计实验展开,详细阐述实验过程、代码实现以及结果分析,帮助读者深入理解时序设计的核心概…

蓝牙系统的核心组成解析

一、硬件层&#xff1a;看得见的物理载体 1. 射频模块&#xff08;Radio Frequency Module&#xff09; 专业描述&#xff1a;工作在2.4GHz ISM频段&#xff0c;支持GFSK/π/4 DQPSK/8DPSK调制方式 功能类比&#xff1a;相当于人的"嘴巴"和"耳朵" 发射端…

猎豹移动(Cheetah Mobile)

本文来自腾讯元宝 公司背景与发展历程 ​成立与早期定位 猎豹移动成立于2010年11月&#xff0c;由金山安全与可牛影像合并而成&#xff0c;初期以移动安全工具和清理软件为核心业务。其明星产品包括《猎豹清理大师》&#xff08;Clean Master&#xff09;和《猎豹浏览器》&…

go的gmp

参考链接&#xff1a;https://www.bilibili.com/video/BV19r4y1w7Nx Golang的GMP调度模型(协程调度器)是其并发编程的核心。GMP代表Goroutine、Machine和Processor三个关键组成部分。Goroutine是Go语言中的轻量级线程&#xff0c;Machine是操作系统的线程&#xff0c;Processor…

Vue3-高级特性

一、Vue中自定义指令 1.认识自定义指令 在Vue的模板语法中我们学习过各种各样的指令&#xff1a;v-show、v-for、v-model等等&#xff0c;除了使用这些指令之外&#xff0c;Vue也允许我们来 自定义自己的指令。 注意&#xff1a;在Vue中&#xff0c;代码的复用和抽象主要还是…

【量化策略】动量突破策略

【量化策略】动量突破策略 &#x1f680;量化软件开通 &#x1f680;量化实战教程 技术背景与应用场景 动量突破策略是一种基于市场趋势的量化交易策略&#xff0c;它通过识别资产价格的动量变化来预测未来的价格走势。这种策略适用于那些价格波动较大、趋势明显的市场环境…

基于CPLD电力/轨道交通3U机箱开关量输出板(DO)

板卡简介&#xff1a; 本板为开关量输出板&#xff08;DO&#xff09;&#xff0c;采用固态继电器用于电平输出或负载驱动&#xff0c;典型输出高电平为DC110V&#xff0c;低电平为0V。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC3.3V&#xff0c;DC15V&#…

【C++经典例题】反转字符串中单词的字符顺序:两种实现方法详解

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;C经典例题 期待您的关注 目录 问题描述 基于快慢指针的解法 基于索引的解法 两种方法的比较 问题描述 在处理字符串相关的问题…

Java基础语法练习45(网络编程)

目录 一、网络的相关概念 1.网络通信 2.网络 3.ip 地址 4.ipv4 地址分类 5.域名 6.网络通信协议 7.TCP 和 UDP 二、InetAddress类 1.相关方法 2.代码示例如下&#xff1a; 三、Socket 1.基本介绍 四、TCP 网络通信编程 1.基本介绍 2.应用示例&#xff1a; 2.1…

【Json—RPC框架】:宏定义不受命名空间限制,续行符的错误使用造成的bug

为什么不受命名空间的限制&#xff1f; 宏处理在预处理阶段&#xff0c; 预处理在编译之前&#xff0c;编译才进行语法分析&#xff0c;语义分析。命名空间也只能限制这部分。 在Json-RPC框架的实现中&#xff0c;遇到如下问题。一开始以为是在实现日志宏的时候&#xff0c;有…

四川省包含哪些水系

背景&#xff1a; 想知道四川省包含哪些水系&#xff0c;以及各个水系的分布&#xff0c;起点、流经省市、终点等 {label: "嘉陵江",value: "嘉陵江",},{label: "渠江",value: "渠江",},{label: "涪江",value: "涪江&q…