[刷题笔记] 高精度加法与高精度乘法

news/2025/3/31 16:22:40/文章来源:https://www.cnblogs.com/Pingjiadoge/p/18796971

之前一直没有做过有关高精度的题,今天做蓝桥杯真题的时候才知道有这种题型(看来埋头硬学不太行),不过幸好发现得早,还有时间补救。

高精度加法

有些题目该出的数据会很大,致使连最大的unsigned long long(264-1)都存不下,c++中有种名为字符串的东西,它的长度可比unsigned long long 长的多,我们可以考虑用它来存储数字;不过string只能存储字符串,所以我们要采取一定的措施,用一定的放法来模拟加法。

在日常生活中,我们计算加法时都是用竖式,所以我们考虑模拟竖式的计算,但是,c++中字符串的遍历方式是从左到右的,为方便计算,我们还得把字符串给翻转一下,我们可以使用reverse函数来实现字符串的翻转,也可以手写函数,手写函数的代码如下:


void reve(string &x)
{long long len = x.size()for(int i = 1;i<=len;i++){char t = x[i];x[i] = x[len - 1 - i];x[len - 1 - i] = t;}
} 

加法的模拟如下:

string high(string a,string b)
{string res;long long maxl = max(a.size(),b.size());//找出字符串的最长长度int up = 0;//up为进位for(int i = 0;i< maxl;i++){int n1 = (i<a.size() ? a[i] - '0' : 0);int n2 = (i<b.size() ? b[i] - '0' : 0);//避免越界,如果超出了小的字符串的范围,小的字符串的数字就始终为0int sum = n1 + n2 + up;//计算每位的和up = sum / 10;//计算进位res.push_back('0' + (sum % 10));//把数字存起来,当然是倒序  }if(up > 0) res.push_back('0' + up); //如果up有剩余,那么还需要进一位return res;
} 

完整代码如下:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;void reve(string &x)
{int len = x.size();for(int i = 0;i<len / 2;i++){swap(x[i], x[len-i-1]);}
}string high(string &a,string &b)
{int up = 0,maxl = max(a.size(),b.size());string res;for(int i = 0;i<maxl;i++){int n1 = (i < a.size()) ? (a[i]-'0') : 0;int n2 = (i < b.size()) ? (b[i]-'0') : 0;int sum = n1 + n2 + up;up = sum / 10;char t = '0' + sum;res.push_back('0'+(sum%10));}if(up > 0) res.push_back('0' + up);return res;
}void solve()
{string a,b;cin >> a >> b;reve(a),reve(b);string ans = high(a,b);reve(ans);cout << ans <<"\n";
}int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int _ = 1;while(_--)solve();return 0;
}

高精度乘法

具体情况和高精度加法差不多,也是需要模拟竖式计算。
首先,依然是需要将字符串翻转过来,可以用reverse函数也可以手写函数,手写函数的方法和加法一样,这里就不在赘述了。
接下来是乘法模拟,为了模拟乘法竖式计算,我们采用与加法计算不同的方法(因为个位数乘完后还需要相加),我们用一个数组来存储结果;用双层循环来枚举其中一个乘数的每一位来与另一个乘数相乘并加在product[i+j]上,这样是为了模拟竖式计算的错位,第一位相乘时,错0位,第二位相乘时,错1位……
由于我们的数字是倒序存储的所以product数组中的数组也是倒序的,与加法不同,我们的数组长度是固定的,难免会出现多于的0,这时我们就应该删去它们,
完成上述操作后,将数字转化为字符串即可。

乘法模拟函数

string high(string a,string b)
{string res;//定义结果vector<int> product(a.size()+b.size(),0);//用来存储每位相乘所得的数字for(int i = 0;i<a.size();i++){for(int j = 0;j<b.size();j++){product[i+j] += (a[i]-'0') * (b[j]-'0');//计算相乘的结果product[i+j+1] += product[i+j]/10;// 处理进位 product[i+j] %= 10;//计算当前位应留下的数}}//假设为12*123,那么第一层循环就是从12中拆除每一位与另一个数相乘,双层循环也可以解决多位数相乘是产生的错位情况	while(product.size() > 1 && product.back() == 0) product.pop_back();//将product数组的大小设为a.size()+b.size()可能会剩下不必要的0,比如10*10 = 100,最后一位就会多出不必要的0,由于数字是倒序存储的,所以不必担心去除数字原有的0	for(int i = product.size()-1; i >= 0; i--) res.push_back(product[i] + '0');//将数字转化为字符串(倒序)return res;//返回结果
}

完整代码如下:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;void reve(string &x)
{for(int i = 0;i<x.size()/2;i++){swap(x[i],x[x.size()-1-i]);}
}string high(string a,string b)
{string res;vector<int> product(a.size()+b.size(),0);for(int i = 0;i<a.size();i++){for(int j = 0;j<b.size();j++){product[i+j] += (a[i]-'0') * (b[j]-'0');product[i+j+1] += product[i+j]/10; product[i+j] %= 10;}}while(product.size() > 1 && product.back() == 0) product.pop_back();for(int i = product.size()-1; i >= 0; i--) res.push_back(product[i] + '0');return res;
}void solve()
{string a,b;cin >> a >> b;reve(a);reve(b);string res = high(a,b);cout << res <<"\n";
}int main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int _ = 1;while(_--)solve();return 0;
}

算法学习,任重而道远啊。

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

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

相关文章

SvelteKit 最新中文文档教程(13)—— Hooks

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

day:32 jmeter操作数据库——安装及认识

一、jmeter数据库安装 1.下载数据驱动,安装数据驱动2、存放四个路径a.jre下的lib C:\ProgramFiles\Java\jre1.8.0_60\libb、存放在jre 下的lib 中的ext 路径: C:\ProgramFiles\Java\jre1.8.0_60\lib\extc、存放在jmeter下的lib 路径:D:\dcs\ruanjian\java\apache-jmeter-3.…

56. W5500以太网模块

一、W5500以太网模块W5500 是一款由 WIZnet 公司生产的以太网控制芯片,它集成了一个全双工的 10/100Mbps 以太网 MAC 和 PHY,以及一个硬件的 TCP/IP 协议栈。W5500 芯片通常被用于嵌入式系统中,为微控制器提供网络连接的能力,使得设备能够通过以太网进行数据传输和通信。W5…

[CF 1870E] Another MEX Problem

思路给你一个序列 \(a\), 让你选出一些不交的子段, 使得它们的 \(\rm{MEX}\) 的异或和最大不难发现因为是异或和, 可以简单转化成 \(\mathcal{O} (n^3)\) 的可行性 \(\rm{dp}\) 然后我进行了对固定右端点 \(r\) 一些优化尝试, 发现都比较寄 然后发现这个题, 它, 对, 右端点, 进…

ChatGPT-4o 更新:原生图像生成技术详解:自回归路线的逆袭

一种新的图像生成范式正在崛起,它不再依赖传统的扩散过程,而是用语言的方式“写”出图像。2025年3月,OpenAI 在更新 GPT-4o 的同时,低调上线了其“原生图像生成”功能。这一功能被嵌入到 GPT-4o 的多模态架构中,与文本、音频等能力无缝协同,带来了显著提升的图像生成质量…

PVE-0-虚拟化实验环境准备

后续实验环境的搭建过程中的技术选型虚拟化环境简介 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机(对计算机物理资源的抽象,实现资源的模拟、隔离和共享)。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在…

【Java 玩转 MCP】手把手教你打造 Git AI 仓库助手

背景 随着人工智能技术的快速发展,开发者工具也在不断进化。Gitee 作为国内领先的代码托管平台,现已推出 MCP (Model Control Protocol) 功能,让开发者能够通过 AI 助手更高效地管理代码仓库。mcp-gitee 是 Gitee 的模型上下文协议 (MCP) 服务器实现,它提供了一组与 Gitee …

探秘Transformer系列之(19)----FlashAttention V2 及升级版本

从零开始解析Transformer,目标是:(1) 解析Transformer如何运作,以及为何如此运作,让新同学可以入门;(2) 力争融入一些比较新的或者有特色的论文或者理念,让老鸟也可以有所收获。探秘Transformer系列之(19)----FlashAttention V2 及升级版本 目录探秘Transformer系列之(…

多线程程序设计(五)——Producer-Consumer

本文摘要了《Java多线程设计模式》一书中提及的 Producer-Consumer 模式的适用场景,并针对书中例子(若干名称有微调)给出一份 C++ 参考实现及其 UML 逻辑图,也列出与之相关的模式。 ◆ 适用场景 为了匹配数据的生产者(Producer)线程与消费者(Consumer)线程之间的处理速…