高精度加法及乘法

目录

字符串的高精度加法

为什么需要高精度加法?

怎么进行高精度加法?

 链表的高精度加法

翻转链表(带虚拟头节点)

字符串的高精度乘法


字符串的高精度加法

大数加法_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/11ae12e8c6fe48f883cad618c2e81475?tpId=196&tqId=37176&ru=/exam/oj

为什么需要高精度加法?

int 能表示的数的范围为 -2147483648(-2^{31}) ~ 2147483647(2^{31}-1),long long int 能表示的最大数为 2^{63}-1,即使一个数据类型能表示的数字再大,也没办法保存所有的数,在加减乘除的计算上也会有溢出的风险,为了减少溢出的风险,可以用 string 保存数字,再来进行计算。

怎么进行高精度加法?

在日常的加法中,我们让两个加数从右往左,从低位开始对齐,对齐后开始进行加法运算,个位和个位相加,十位和十位相加,如果相加之和大于10,则需要进位,如图所示:

高精度加法就是要模拟平时加法的过程。

假设相加得到的字符串为 ret,按照字符串的存储方式,字符串从左往右,对应数字从高位到低位,所以两个字符串都从后往前遍历,访问一个数字便相加,把相加的结果尾插到 ret 中,模拟每一位对齐后相加。

每一位数相加的结果如果大于等于10,就需要进位,那我们怎么得到进位的值?

我们不能单纯地让每一位数进行相加和尾插,我们需要定义一个变量 tmp ,来存储我们每一位数相加的和,tmp%10 就可以得到 tmp 的个位,即我们要尾插的数,尾插后 tmp/= 10,就可以得到进位的数,进行下一位的相加时,直接把每一位数相加到 tmp 中,便完成了进位操作

在相加时,不可避免会遇到两个数的位数不一样,有的数4位,有的数2位,怎么处理位数不一样的情况?

在每一位相加前,我们需要判断当前的字符串的每一位是否已经相加结束,如果已经相加结束了,就不再访问这个字符串了。

因为我们是把和尾插到 ret 中,所以和也是反的,我们需要把 ret 进行 reverse,就可以得到最终结果。

class Solution {
public:string solve(string s, string t) {int i=s.size()-1;int j=t.size()-1;string ret;//两数相加之和int tmp=0;//记录每一位相加的和while(i>=0 || j>=0 || tmp){if(i>=0) tmp+=(s[i--]-'0');//该位不是空,才可以相加if(j>=0) tmp+=(t[j--]-'0');ret+=(tmp%10+'0');//相加后取模,尾插tmp/=10;//除以10,得到的商就是需要进位的数}reverse(ret.begin(),ret.end());//把字符串逆序return ret;}
};

 链表的高精度加法

链表相加(二)_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/c56f6c70fb3f4849bc56e33ff2a50b6b?tpId=196&tqId=37147&ru=/exam/oj

和字符串的高精度加法一样,我们需要从后面开始访问链表,但是题目提供的链表是单链表,不是双向循环链表,不支持从后向前遍历链表,所以需要自己写一个函数,翻转链表。

翻转链表(带虚拟头节点)

在翻转链表时,我们定义一个虚拟头节点,方便头插

1、没有虚拟头节点时,我们需要判断链表是否为空,不为空则直接头插,为空则需要特殊处理

2、设置了虚拟头节点之后,无论链表是否为空,不需要特殊处理,直接插入到虚拟头节点的后面即可(图中 0 为虚拟头节点)

翻转函数后得到的链表带虚拟头节点,在返回时,不需要返回虚拟头节点(不可以返回不属于原链表的结点),所以需要把虚拟头节点删除

链表翻转后的高精度加法和字符串的高精度加法原理相同。 

class Solution {
public:ListNode* reverse(ListNode* head){ListNode* newhead=new ListNode(0);//虚拟头节点ListNode* cur=head;//遍历headwhile(cur){ListNode*next=cur->next;cur->next=newhead->next;newhead->next=cur;cur=next;}cur=newhead->next;//保存虚拟头节点的下一个结点delete newhead;//删除虚拟头节点newhead=cur;return newhead;//返回翻转后的链表}ListNode* addInList(ListNode* head1, ListNode* head2) {head1=reverse(head1);head2=reverse(head2);ListNode*cur1=head1;ListNode*cur2=head2;ListNode* ret=new ListNode(0);//虚拟头节点ListNode* end=ret;int tmp=0;while(cur1 || cur2 ||tmp){if(cur1) {tmp+=cur1->val;cur1=cur1->next;}if(cur2){tmp+=cur2->val;cur2=cur2->next;}ListNode* t=new ListNode(tmp%10);end->next=t;end=end->next;tmp/=10;}cur1=ret->next;delete ret;//删除虚拟头节点ret=cur1;ret = reverse(ret);//把ret翻转,得到最终结果return ret;}
};

字符串的高精度乘法

大数乘法_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/c4c488d4d40d4c4e9824c3650f7d5571?tpId=196&tqId=37177&ru=/exam/oj

关于高精度乘法,有一个很巧妙的方法, 同样也是模拟乘法:

假设现在需要计算 1234 * 24 的积,原本 1234 对应的下标从左往右对应从 1 到 4,翻转后,得到的字符串下标从左往右对应从 4 到 1,24同理,原本 1234 和 24 中 ' 4 ' 的下标是不对齐的,翻转后对齐了,之后我们可以进行相乘。

下标为 i 的数 和下标为 j 的数相乘,相乘的结果放在下标为 i+j 的位置,例如下标为 2 的数 2 和下标为 1 的数 2,相乘的结果 4 应该放在下标为 3 的位置,所有数相乘之后,再把对应位置的数相加并进位,翻转结果字符串即可,如图所示:

但是我们需要处理前导 0 的情况,比如 1000 * 0,得到的字符串为 0000,但我们只需要结果 0,所以我们当字符串的长度大于 1 且字符串的末尾为 0 时,需要尾删 0.

class Solution {
public: string solve(string s, string t) {reverse(s.begin(),s.end());//翻转字符串reverse(t.begin(),t.end());int m=s.size(),n=t.size();vector<int> v(m+n);for(int i=0;i<m;i++){for(int j=0;j<n;j++){v[i+j]+=(s[i]-'0')*(t[j]-'0');}}int tmp=0;string ret;for(int i=0;i<v.size();i++){tmp+=v[i];ret+=(tmp%10+'0');tmp/=10;}while(ret.size()>1 && ret.back()=='0') ret.pop_back();//处理前导0reverse(ret.begin(),ret.end());return ret;}
};

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

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

相关文章

linux下查看前10最耗内存的进程

lunux查找占用内存前10的进程 1、使用Top命令查询进程 输入 top 命令&#xff0c;然后按下大写M按照内存MEM排序&#xff0c;按下大写P按照CPU排序。 2、查询占用CPU最高的前10个进程 ps aux|head -1;ps aux|grep -v PID|sort -rn -k 3|head 3、查询占用内存最大的前10个进程…

2024年度西安市创新联合体备案申报条件时间要求须知

一、申报条件 组建市级创新联合体需具备牵头单位、成员单位、组建协议、首席科学家等四个条件。 (一)牵头单位 1.牵头单位应为在西安市注册登记的省市产业链龙头骨干企业&#xff0c;重点支持市级重点产业链“链主”企业; 2.牵头单位一般为1家。 (二)成员单位 1.成员单位…

excel 按照姓名日期年月分组求和

excel 需要按照 姓名 日期的年份进行金额求和统计&#xff0c;采用sumifs 进行统计 注意&#xff1a;sumifs 不支持 合并列拆分计算&#xff0c;合并列只会计算一个值 表格数据大概如下&#xff1a;(sheet) ABC姓名日期金额A2023/01/01500A2023/01/151500B2023/01/01200B202…

python 调试 c++源码

1. gdb常用调试命令概览和说明 2. 编译c库设置Debug模式 cmake设置debug 在CMake中设置debug模式通常意味着启用调试信息和优化。以下是一个简单的CMakeLists.txt文件示例&#xff0c;展示了如何设置项目以便在Debug模式下构建&#xff1a; cmake_minimum_required(VERSION 3…

cad中快速计算多个矩形面积的方法

1、输入命令reg&#xff0c;选中矩形创建面域 2、输入命令uni,选中刚刚创建的面域&#xff0c;组合成一个面域 3、输入命令&#xff1a;LI &#xff0c;选中面域&#xff0c;即可查看面积和周长 需注意的一点&#xff0c;开始创建的矩形或者多段线要在一个面内&#xff0c;就是…

[沉浸式翻译]最好的网页翻译工具

沉浸式翻译 沉浸式翻译是一种翻译工具&#xff0c;它提供了多种平台的支持&#xff0c;包括桌面端的Edge、Chrome、Firefox、Safari以及移动端的iOS和Android。用户可以在这些平台上安装沉浸式翻译的插件&#xff0c;以便在浏览网页时获得翻译服务。 浏览器的安装教程 详细的…

WEB网站服务器安全漏洞扫描环境搭建及漏洞工具扫描

一、适用环境 1、企业自建有门户网站&#xff1b; 2、使用Struts框架的WEB网站&#xff1b; 3、网站服务器涉及有数据库之类的项目&#xff0c;如&#xff1a;微信登录、手机登录、充值、收费等。 4、使用安卓版、苹果版、电脑版结合的缴费类网站平台。 5、方便但需提高安全性…

排列对称串

Description:很多字串&#xff0c;有些是对称的&#xff0c;有些是不对称的&#xff0c;请将那些对称的字事按从小到大的顺序输出&#xff0c;字事先以长度论大小&#xff0c;如果长度相同&#xff0c;再以ASCI码值为大小标准 Input.输入数据中含有一些字串(1≤串长≤256)。 #…

气膜游泳馆有哪些应用优势呢?-轻空间

气膜游泳馆作为一种利用气膜技术建造的室内体育场馆&#xff0c;具有环保、节能、灵活、美观等特点&#xff0c;适合在各种气候和地形条件下使用。以下是气膜游泳馆具有的应用优势&#xff1a; 1. 全年四季恒温恒湿&#xff1a;气膜游泳馆内部设有智能化的恒温恒湿系统&#xf…

基础环境:wsl2安装Ubuntu22.04 + miniconda

服务器相关信息&#xff1a; Thinkpad p1 gen5 64G 2T 3080ti&#xff0c;自带的有nvidia-smi显卡驱动。使用wsl2安装Ubuntu22.04 miniconda目标&#xff1a;安装gpu版本的PyTorch2.1.2&#xff08;torch2.1.2/cu117 torchvision0.16.2/cu117&#xff09; 处理器 12th Gen I…

ubuntu扩展根目录磁盘空间

ubuntu扩展根目录磁盘空间 扩展虚拟机磁盘空间 查看现有磁盘状态 查询现有分区状态&#xff0c;/dev/sda是我们要扩展的磁盘 fdisk -l 开始进行磁盘空间的扩容 parted /dev/sda#扩展3号分区的空间 resizepart 3刷新分区空间 resize2fs /dev/sda3查询扩展结果&#xff0c;…

Linux安装Matlab运行时

一般而言&#xff0c;安装Matlab的linux系统是带桌面版的&#xff0c;如果没带&#xff0c;不在本教程范围内。 一、下载Matlab 下载地址&#xff1a;MATLAB Runtime - MATLAB Compiler - MATLAB 本教程使用R2020b(9.9) 二、linux系统中进行解压 将zip传入linux系统&#xf…

EigenLayer生态全解析:再质押与AVS崛起的序章

基于以太坊网络的再质押协议EigenLayer提出了利用为以太坊网络验证而质押的ETH来与其他协议共享安全性和资本效率&#xff0c;同时为协议参与者提供额外利息。在AVS、再质押、积分系统等概念的推动下&#xff0c;逐渐形成一个庞大的生态系统&#xff0c;从2024年初到现在EigenL…

使用JS代理 实现大对象的功能拆解

序言 在Android开发中&#xff0c;可以通过webView的addJavascriptInterface方法注入一个对象到网页中。但是随着开发的需求越来越多。这个对象身上的方法也越来越多。这个对象对应的java类&#xff0c;体积越来越大&#xff0c;不利于维护。为了在不影响之前代码的基础上。把…

【C++干货基地】深度理解C++中的高效内存管理方式 new delete

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

Golang基础5-指针、结构体、方法、接口

指针 和c/c类似&#xff0c;但是go语言中指针不能进行偏移和运算&#xff0c;安全指针 &&#xff08;取地址) *(根据地址取值) nil(空指针&#xff09; make和new之前对比&#xff1a;make用于初始化slice&#xff0c;map&#xff0c;channel这样的引用类型 而new用于类…

Metasploit Framework(MSF)从入门到实战(一)

MSF的简介 目前最流行、最强大、最具扩展性的渗透测试平台软件 基于Metasploit进行渗透测试和漏洞分析的流程和方法 2003年由HD More发布第一版&#xff0c;2007年用ruby语言重写 架集成了渗透测试标准 (PETS&#xff09; 思想 一定程度上统一了渗透测试和漏洞研究的工作环…

针孔相机模型原理坐标系辨析内参标定流程内参变换

针孔相机的内参标定 针孔相机原理真空相机模型图片的伸缩和裁剪变换 内参标定———非线性优化张正定标定详细原理(含公式推导)通过多张棋盘格照片完成相机的内参标定流程(C代码)其他工具箱 相机分为短焦镜头和长焦镜头&#xff0c;短焦镜头看到的视野更广阔&#xff0c;同样距…

白平衡简介

文章目录 白平衡的概念白平衡的调节常见的白平衡模式 白平衡的概念 白平衡是指摄影、摄像和显示技术中的一项重要概念&#xff0c;用于调节图像中的白色或中性灰色的色彩&#xff0c;使其看起来在不同光源条件下都是准确的白色或灰色。白平衡的主要目的是确保图像的色彩准确性…

C语言 | Leetcode C语言题解之第49题字母异位词分组

题目&#xff1a; 题解&#xff1a; /*1.将字符串原串与副本进行绑定成一个节点2.对字符串副本进行按ascii码表进行从小到大排序3.按照字符串进行比较排序4.合并 */ typedef struct Node{char*s;char*s_vice;int len; }Node;void sortShellChar(char*s,int len){for(int dista…