【六十一】【算法分析与设计】高精度乘法和高精度除法

高精度乘以单精度

由于计算机的基本数据类型如 intlong 有其大小限制,当我们需要进行超出这些基本类型范围的计算时,就需要使用大数乘法技术。一种简单的大数乘法算法——单精度乘高精度数算法。这种方法特别适用于将一个大数(用字符串表示)与一个较小的整数相乘。

把迭代过程想象成许多节点的连接,每一个节点拥有的信息数量是相同的。

每当进入一个新的节点,信息变量存储的是上一个节点的信息。利用上一个节点的信息维护当前节点的信息,然后完成我们希望的工作。

这样的好处是明确统一了维护变量的时机----进入节点之后统一维护。

这样就避免了有一些变量在上一节点维护,有一些变量在当前节点维护而造成的混乱。

注意进入下一节点的条件和操作。

 
static string multiply_1(const string& a, const string& _b) {// 如果乘数是0或原数是0,直接返回"0"if (b == 0 || a == "0") return "0";string c;  // 结果字符串int b = stoi(_b);  // 将单精度数字符串转换为整数int i = a.size() - 1;  // 从字符串的最后一个字符开始处理int carry = 0;  // 进位初始化为0int sum = 0;  // 当前位的乘积结果加上进位while (i >= 0 || sum / 10) {  // 当还有数字需要处理或者进位不为0时继续循环carry = sum / 10;  // 更新进位int num = i >= 0 ? a[i] - '0' : 0;  // 获取当前位的数字,如果i小于0则取0sum = num * b + carry;  // 当前位数字与b相乘再加上进位c.push_back(sum % 10 + '0');  // 将得到的个位数转换为字符后加到结果字符串i--;  // 移动到下一位}reverse(c.begin(), c.end());  // 结果字符串需要翻转,因为加入时是从低位到高位return c;  // 返回结果字符串
}

高精度乘以高精度

在计算机编程和数值算法中,处理非常大的数字——特别是超出标准数据类型限制的数字——是一个常见且重要的问题。这是一个高精度乘法算法的实现,该算法使用字符串表示的两个大数进行相乘操作,返回它们的乘积,同样以字符串的形式表示。

本算法是高精度乘法的一种实现,通常称为“长乘法”或“列乘法”,该方法在手工乘法的基础上进行了数字化实现。

初始化变量:

 
int n = a.size(), m = b.size();
string c(n + m, '0');

  代码开始首先确定两个输入字符串 ab 的长度,分别为 nm。结果字符串 c 初始化为长度为 n + m 的字符串,所有位填充为 '0',这是基于最大位数的估算——两个数相乘的结果位数不会超过它们的位数之和。

嵌套循环处理每位乘法并累加:

for (int i = n - 1; i >= 0; --i) {int carry = 0;int sum = 0;for (int j = m - 1; j >= 0 || sum / 10; --j) {carry = sum / 10;sum = (c[i + j + 1] - '0') + (a[i] - '0') * (j >= 0 ? b[j] - '0' : 0) + carry;c[i + j + 1] = (sum % 10) + '0';}
}

  在这个核心的部分,两层循环分别遍历字符串 ab 的每个字符。外循环逆向遍历 a,内循环逆向遍历 b,同时考虑累计的进位(carry)。每次乘积计算后,将结果累加到对应的结果位置,并更新进位。如果内循环结束后仍有未处理的进位,它也将被正确地添加到结果中。

处理前导零并返回结果:

 
size_t startpos = c.find_first_not_of("0");
if (startpos != string::npos) {return c.substr(startpos);
}
return "0";

  乘法完成后,结果字符串 c 可能包含前导零。通过 find_first_not_of("0") 方法找到第一个非零字符的位置,从而移除前导零。如果字符串全为零(未找到非零字符),则返回 "0"

 
static string multiply_2(const string& a, const string& b) {// 获取两个数字的长度int n = a.size(), m = b.size();// 初始化结果字符串为n+m位,所有位初始化为'0'string c(n + m, '0');// 进位和临时求和变量初始化int carry = 0;int sum = 0;// 从a的最后一位开始,向前遍历每一位for (int i = n - 1; i >= 0; --i) {// 对每一位a[i],重置进位和求和变量carry = 0;sum = 0;// 内层循环:从b的最后一位开始,向前遍历每一位for (int j = m - 1; j >= 0 || sum / 10; --j) {// 更新进位值carry = sum / 10;// 计算当前位的乘积加上之前的进位和结果中已有的数值sum = (c[i + j + 1] - '0') + (a[i] - '0') * (j >= 0 ? b[j] - '0' : 0) + carry;// 更新结果字符串的对应位置c[i + j + 1] = (sum % 10) + '0';}}// 移除结果字符串中的前导零size_t startpos = c.find_first_not_of("0");if (startpos != string::npos) {return c.substr(startpos); // 如果找到非零字符,则返回从此位置到末尾的子字符串}// 如果全为零,则返回"0"return "0";
}

高精度除以单精度

在计算大数运算,特别是在处理如金融分析、科学计算和编程领域中的数据时,常常需要进行精确的除法操作。当我们面对的数字超出了标准数据类型(如 int 或 long)的处理范围时,就需要用到高精度的算法来处理这些数据。我们将详细介绍一种使用字符串表示的大数进行除法运算的高精度算法。

该算法的主要目的是将一个由字符串表示的大数 a 除以一个较小的整数 _b,并以字符串的形式返回商。这种方法在处理非常大的数时特别有用,因为它避开了传统数值类型的限制。

初始化和转换:

 
string c;  // 存放结果的字符串
int b = stoi(_b);  // 将字符串 _b 转换为整数 b
int nums = 0;  // 用于暂存中间结果的数值
int i = 0;  // 字符串 a 的索引,从第一个字符开始

初始阶段包括设置用于储存结果的字符串 c,将除数 _b 从字符串转换为整数 b,以及初始化辅助变量 nums(用于储存部分除法结果)和索引 i

遍历并计算每一步的商:

 
while (i < a.size()) {nums = nums % b;  // 取上一次的余数nums = nums * 10 + a[i] - '0';  // 将余数乘以10后加上当前字符表示的数字c.push_back(nums / b + '0');  // 将当前得到的商转换为字符后加入结果字符串++i;  // 移动到下一个字符
}

在这个循环中,算法逐个处理字符串 a 中的每个数字字符。首先,计算当前累积值 numsb 的余数,然后将这个余数乘以10并加上新的数字,模拟手工除法中的“下拉”一位的步骤。计算得到的商被转换为字符并添加到结果字符串 c 中。

处理结果中的前导零:

 
size_t startpos = c.find_first_not_of("0");
if (startpos != string::npos)  // 如果找到非零字符return c.substr(startpos);  // 返回从这个位置到字符串末尾的子字符串
return "0";  // 如果全部都是零,则返回"0"

最后,算法检查结果字符串 c 中的前导零,并将它们移除。如果字符串中没有非零数字,函数返回 "0"

这种高精度除法算法适用于处理大规模数字,特别是当常规整型无法处理这些数据时。它模拟了人们在纸上进行除法的传统方法,因此容易理解和实现。

 
static string divide_1(const string& a, const string& _b) {string c;  // 存放结果的字符串int b = stoi(_b);  // 将字符串 _b 转换为整数 bint nums = 0;  // 用于暂存中间结果的数值int i = 0;  // 字符串 a 的索引,从第一个字符开始// 遍历字符串 a 的每一个字符while (i < a.size()) {nums = nums % b;  // 取上一次的余数nums = nums * 10 + a[i] - '0';  // 将余数乘以10后加上当前字符表示的数字c.push_back(nums / b + '0');  // 将当前得到的商转换为字符后加入结果字符串++i;  // 移动到下一个字符}// 找到结果字符串中第一个不是'0'的字符位置size_t startpos = c.find_first_not_of("0");if (startpos != string::npos)  // 如果找到非零字符return c.substr(startpos);  // 返回从这个位置到字符串末尾的子字符串return "0";  // 如果全部都是零,则返回"0"
}

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

[ LeetCode ] 题刷刷(Python)-第58题:最后一个单词的长度

题目描述 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 示例 1&#xff1a; 输入&#xff1a;s "Hello World" 输出&…

(1)认识人工智能

第一章 认识人工智能 引言 本人目前大三&#xff0c;双非一本的人工智能专业&#xff0c;代码能力不算太差&#xff0c;做过项目&#xff0c;也打了比赛&#xff0c;获了奖&#xff0c;但是走技术路线总会有否定自己的感觉&#xff0c;可能是感觉自己的才能没有在搞技术方面实…

UML绘制

processon官网 https://www.processon.com/template_create 官方学习地址 https://plantuml.com/zh/class-diagram 在Android studio 中自动生成类图 https://blog.csdn.net/zyfzhangyafei/article/details/126636358 plantUML 在线编辑 https://www.plantuml.com/plantuml/um…

小红书电商运营实战课,从0打造全程实操(65节视频课)

课程内容&#xff1a; 1.小红书的电商介绍 .mp4 2.小红书的开店流程,mp4 3.小红书店铺基础设置介绍 ,mp4 4.小红书店铺产品上架流程 .mp4 5.客服的聊天过程和子账号建立 .mp4 6.店铺营销工具使用和后台活动参加 .mp4 7.小红书产品上架以及拍单教程,mp4 8.小红书如何选品…

数据分析_商品维度占比及变化可视化分析(Pandas和Matplotlib)

数据分析_商品维度占比及变化可视化分析(Pandas和Matplotlib) 分析维度包括: 各商品年度销量占比 各商品月度销量变化 构建测试数据 这里你可以了解到: 如何生成时间相关的数据。 如何从列表&#xff08;可迭代对象&#xff09;中生成随机数据。 Pandas 的 DataFrame 自…

IDM下载管理工具的详细介绍

第一章:IDM简介与安装 Internet Download Manager(IDM)是一款备受欢迎的下载管理工具,具有强大的下载加速功能和丰富的功能特性。本章将介绍IDM的基本信息,以及如何进行安装和设置。 1.1 IDM简介 IDM是由美国公司Tonec Inc.开发的一款下载管理器,它能够提供强大的下载…

eggjs 日志记录配置 记录

eggjs日志配置 ## //config.default.js // 日志配置config.logger {level: "INFO", // SILENT, DEBUG, INFO, WARN, ERROR, FATALconsoleLevel: "DEBUG", // 控制台日志输出级别dir: "/logs", // 日志文件的存储目录type: "dateFile…

MVC、MVP、MVVM

MVC、MVP和MVVM是三种流行的软件架构模式&#xff0c;它们被设计来组织代码结构&#xff0c;提高代码的可维护性、可测试性和可扩展性。尽管它们在高层次目标上一致&#xff0c;但在实现细节和应用交互方式上各有特点。 MVC&#xff08;Model-View-Controller&#xff09; Mo…

【JVM系列】关于静态块、静态属性、构造块、构造方法的执行顺序

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

2.Vue简介

Vue简介 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;V…

【网站项目】“最多跑一次”小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【一竞技DOTA2】双冠王N0tail将发布新书自传《性格胜过天赋》

1、近日Ti双冠王N0tail&#xff0c;在个人推特上宣布将发布自己的自传《性格胜过天赋》。N0tail职业生涯豪夺两届Ti冠军&#xff0c;700万美元个人生涯奖金亦是电竞史最高的传奇选手。 “经过许多年的努力和收到的大量请求&#xff0c;我将发布我的自传新书《性格胜过天赋》&am…

C++ 核心编程 - 引用

文章目录 2.1 引用的基本使用2.2 注意事项2.3 引用作函数参数2.4 引用作函数返回值2.5 引用的本质2.6 常量引用 2.1 引用的基本使用 作用&#xff1a; 给变量起别名&#xff0c;语法为 数据类型 &别名 原名 int main(){int a 100;int &b a;cout << "a …

特征值eigenvalue与特征向量eigenvector

特征值&#xff0c;特征向量概念 在线性代数中&#xff0c;对于一个给定的线性变换A&#xff0c;他的特征向量v经过这个线性变换的作用之后&#xff0c;得到的新向量仍然与原来的 v v v保持在同一条直线上。但长度或方向也许会改变。即&#xff1a; A v Av Av λ v \lambda…

戒烟生活记录

今天是2024年4月15日&#xff0c;从大前天也就是12号下班后&#xff0c;吃的有一点饱&#xff0c;就感觉身体及其难受&#xff0c;气短呼吸不上&#xff0c;我查了后可能是心脏的问题&#xff0c;并且晚上睡觉有一种呼吸不上&#xff0c;憋气的感觉&#xff0c;然后我就又开始决…

强化网络安全防线,您的等级保护措施到位了吗?

在这个信息化飞速发展的时代&#xff0c;网络安全已经成为我们每个人都需要关注的问题。无论是企业还是个人&#xff0c;我们的工作和生活都越来越依赖于网络。确保网络环境的安全&#xff0c;防止信息泄露和网络攻击&#xff0c;已经成为了一项至关重要的任务。等级保护制度作…

如何做一个优秀的系统工程师?

一、背景 做好一个优秀系统工程师的关键在于其在产品开发生命周期中对需求分析的有效把握与运用&#xff0c;这个过程直接影响到系统的整体架构设计、规格参数的明确设定以及业务流程的深度挖掘与优化。需求分析不仅是理解用户实际问题的核心环节&#xff0c;更是界定系统开发…

无限滚动分页加载与下拉刷新技术探析:原理深度解读与实战应用详述

滚动分页加载&#xff08;也称为无限滚动加载、滚动分页等&#xff09;是一种常见的Web和移动端应用界面设计模式&#xff0c;用于在用户滚动到底部时自动加载下一页内容&#xff0c;而无需点击传统的分页按钮。这种设计旨在提供更加流畅、连续的浏览体验&#xff0c;减少用户交…

Go语言中通过数据对齐降低内存消耗和提升性能

数据对齐是一种安排数据分配方式以加速 CPU 访问内存的方法。 不了解这个概念会导致额外的内存消耗甚至性能下降。 要了解数据对齐的工作原理&#xff0c;让我们首先讨论没有它会发生什么。假设我们分配两个变量&#xff0c;一个 int32 类型的 &#xff08;32 B&#xff09; 和…

docker-compose 安装MongoDB续:创建用户及赋权

文章目录 1. 问题描述2. 分析2.1 admin2.2 config2.3 local 3. 如何连接3.解决 1. 问题描述 在这一篇使用docker-compose创建MongoDB环境的笔记里&#xff0c;我们创建了数据库&#xff0c;但是似乎没有办法使用如Robo 3T这样的工具去连接数据库。连接的时候会返回这样的错误&…