【基础算法】大数运算问题

news2025/1/12 0:51:07

🌹作者:云小逸
📝个人主页:云小逸的主页
📝Github:云小逸的Github
🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟
👏专栏:C++👏 👏专栏:Java语言👏👏专栏:Linux学习👏
👏专栏:C语言初阶👏👏专栏:数据结构👏👏专栏:备战蓝桥杯👏

文章目录

  • 前言
    • AcWing 3482. 大数运算
    • 题目描述
    • 输入格式
    • 输出格式
    • 数据范围
    • 输入样例
    • 输出样例
    • 题解
    • C++代码
    • 解题思想:
    • 需要注意:由于两个高精度数的乘积有可能超出该类型能够表示的最大范围,所以在计算过程中可能无法存储完整结果,而需要进行分段计算。具体来说,我们可以先将a数组中的每一位分别与b数组中的每一位相乘,然后将所有这些积按位相加,并且在该位处存储进位的值。在最后输出答案时,我们需要忽略掉所有前缀0,只输出第一个非零数及其后面的数字。
  • 最后


前言

今天我们继续学习算法,加油。这篇文章写的是大数运算问题。希望这篇可以有幸帮助到你,码字不易,请多多支持。
在这里插入图片描述


AcWing 3482. 大数运算

题目描述

给定两个整数a和b,计算它们的和、差、积。

输入格式

共两行,每行包含一个整数。

输出格式

共三行,分别输出它们的和、差、积。

注意:在输出结果时,不能有多余的前导零。

数据范围

输入数的绝对值不超过 1 0 400 10^{400} 10400,且保证存在结果。

输入样例

20000000000000000
4000000000000000

输出样例

24000000000000000
16000000000000000
80000000000000000000000000000000

题解

本题主要考察高精度运算。具体来说,需要实现高精度加减乘法3个算法。

时间复杂度

高精度加法、减法、乘法的时间复杂度均为 O ( n ) O(n) O(n)

空间复杂度

本算法空间复杂度为 O ( n ) O(n) O(n)

C++代码

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

const int N = 1e6+10;
int a[N], b[N], c[N];
vector<int> mul[N];

void add(int a[], int b[], int c[])
{
    int t = 0;
    for(int i = 0; a[i] != -1 || b[i] != -1; i++) 
    {
        if(a[i] != -1) t += a[i];
        if(b[i] != -1) t += b[i];
        c[i] = t % 10; // 当前位的值
        t /= 10; // 进位
    }
    if(t > 0) c[strlen(a)] = t; // 最高位进位
    else c[strlen(a)] = -1; // 标记末尾,避免后续运算错误
}

void sub(int a[], int b[], int c[])
{
    int t = 0;
    for(int i = 0; a[i] != -1 || b[i] != -1; i++)
    {
        if(a[i] != -1) t += a[i];
        if(b[i] != -1) t -= b[i];
        if(t < 0) c[i] = t + 10, t = -1; //当前位需要借位
        else c[i] = t, t = 0; // 当前位不需要借位
    }

    while(c[strlen(a)-1] == 0 && strlen(a) > 1)
        --c[strlen(a)-1];
    c[strlen(a)] = -1;
}

void mul(int a[], int b[], vector<int> &res)
{
    res.clear();

    if(a[0] == 0 || b[0] == 0)
    {
        res.push_back(0);
        return ;
    }

    for(int i = 0; b[i] != -1; i++)
    {
        int t = 0;
        for(int j = 0; a[j] != -1; j++)
        {
            t += a[j] * b[i];
            if(i == 0) mul[i].push_back(t % 10); // 将第一次求乘积的结果缓存起来
            else mul[i][j+i] += t % 10; // 在上一次基础上进行累加
            t /= 10;
        }
        if(t > 0) mul[i].push_back(t); // 存储最高位的进位
    }

    int t = 0;
    for(int i = 0; ; i++)
    {
        bool flag = true;
        for(int j = 0; j < b[strlen(b)-1]-'0'; j++)
            if(mul[j][i] != 0)
                flag = false;

        if(flag) break;

        for(int j = 0; j < b[strlen(b)-1]-'0'; j++)
            if(mul[j][i] != -1)
                t += mul[j][i];
        res.push_back(t % 10);
        t /= 10;
    }
    while(t != 0)
    {
        res.push_back(t % 10);
        t /= 10;
    }
}

int main()
{
    string str;
    cin >> str;
    memset(a, -1, sizeof a), memset(b, -1, sizeof b), memset(c, -1, sizeof c);

    for(int i = 0; i < str.size(); i++) a[str.size()-i-1] = str[i]-'0';
    cin >> str;
    for(int i = 0; i < str.size(); i++) b[str.size()-i-1] = str[i]-'0';

    add(a, b, c);
    for(int i = strlen(c)-1; i >= 0; i--) cout << c[i];
    cout << endl;

    sub(a, b, c);
    for(int i = strlen(c)-1; i >= 0; i--) cout << c[i];
    cout << endl;

    mul(a, b, mul[0]);
    for(int i = mul[0].size()-1; i >= 0; i--) cout << mul[0][i];
    cout << endl;

    return 0;
}

解题思想:

该问题主要考察高精度加减乘法3个算法的实现。

高精度加法:

从低位到高位逐位相加,遇到有任意一个数位没有值时,置为0即可。具体步骤如下:

  1. 从低位到高位,依次将a、b的每一位相加
  2. 若某一位不存在,则视其为0
  3. 若当前位相加后产生了进位,则将进位留到下一位相加
  4. 若最高位计算出来还有进位,则把进位存储在最高位

高精度减法:

与高精度加法类似,从低位到高位逐位相减,遇到被减数小于减数则向高位借位即可。具体步骤如下:

  1. 从低位到高位,依次将a、b的每一位相减
  2. 若某一位不存在,则视其为0
  3. 若被减数小于减数,则需要向高位进行借位操作
  4. 去除结果数组中的前导0(注意结果如果为0需要特判)

高精度乘法:

高精度乘法是通过一个双重循环的方式求解的,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

具体来说,我们先用第二层循环按照个位、十位、百位……的顺序,将a数组中的每一位都与b数组中的每一位相乘,并记录它们的积。然后我们用第二层循环按照十位、百位、千位……的顺序继续进行运算,把前面得到的所有积加起来即可。

需要注意:由于两个高精度数的乘积有可能超出该类型能够表示的最大范围,所以在计算过程中可能无法存储完整结果,而需要进行分段计算。具体来说,我们可以先将a数组中的每一位分别与b数组中的每一位相乘,然后将所有这些积按位相加,并且在该位处存储进位的值。在最后输出答案时,我们需要忽略掉所有前缀0,只输出第一个非零数及其后面的数字。

最后

十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:

1、划清和别人的界限。别人怎么看你,跟你毫无关系,你要怎么活,也跟别人没有任何关系,撇清别人,才能精力旺盛。

2、避免内耗,就是不要想太多。想完这个人的事,接下来再想另外一个人的事情,没完没了,每天都处在内耗中。要一直练习,谁的事情都不想,不要形成内耗。

3、要有一个好的状态,不属于任何人,不拥有任何人,减少期待,好好生活。

4、不要有太多的欲望,放下一切执念,不要让欲望牵着鼻子走。而且要让现实和踏实让我们好好地走。

5、不要整天多愁善感,说实话,真的没有几个人在乎你,他们根本不会把你放在心上和脑中,做一个俗人吧。

最后如果觉得我写的还不错,请不要忘记点赞✌,收藏✌,加关注✌哦(。・ω・。)

愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚菜鸟逐渐成为大佬。加油,为自己点赞!

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

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

相关文章

Python高光谱遥感数据处理与机器学习(最新的技术突破讲解和复现代码)

将高光谱技术与Python编程工具结合起来&#xff0c;聚焦高频技术难点&#xff0c;明确开发要点&#xff0c;快速复现高光谱数据处理和分析过程&#xff0c;并对每一行代码进行解析&#xff0c;对学习到的理论和方法进行高效反馈。实践篇&#xff0c;通过高光谱矿物识别&#xf…

了解这个项目进度跟踪管理工具,轻松掌握项目进度

白天开会晚上干活的PM和战场上的将军没有区别&#xff0c;产品研发如同组团杀敌&#xff0c;团队配合最为重要。Zoho Projects项目管理工具&#xff0c;适用于各种规模和需求的公司。 一、需求管理 在项目中&#xff0c;我们使用它Zoho收集整理各方反馈&#xff0c;快速处理工单…

自媒体达人养成计划(ChatGPT+new bing)

本节课我们来探索如何使用GPT帮助我们成为自媒体达人&#xff0c;快速赚到一个小目标&#xff01;在此之前&#xff0c;我们需要先做些准备工作~ 首先是平台选取&#xff0c;写文章第一件事就是要保证内容的有效性和准确性&#xff0c;不然就成为营销号了嘛&#xff0c;所以我…

5---最长回文字串

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&…

改进沙猫群优化算法(ISCSO)-附代码

改进沙猫群优化算法(ISCSO) 文章目录 改进沙猫群优化算法(ISCSO)1.沙猫群优化算法2. 改进沙猫群优化算法2.1 混沌映射初始化2.2 引入互利共生策略2.3 引入莱维飞行策略 3.实验结果4.参考文献5.Matlab代码6.Python代码 摘要&#xff1a;对沙猫群优化算法进行改进。在改进的沙猫群…

Vue.js 教程---菜鸟教程

文章目录 Vue.js 教程Vue.js 安装Vue.js 起步Vue.js 模板语法插值指令用户输入过滤器缩写 Vue.js 条件语句Vue.js 循环语句Vue.js 计算属性Vue.js 监听属性Vue.js样式绑定 Vue.js 教程 本教程主要介绍了 Vue2.x 版本的使用 第一个实例&#xff1a; <body> <div id&…

Linux 信号学习

Linux 信号学习 信号量的基本概念信号产生的条件信号如何被处理信号的异步特质 信号的分类可靠信号/不可靠信号实时信号/非实时信号 常见信号与默认行为信号处理signal() 函数sigaction()函数 向进程发送信号kill() 函数raise() 函数 alarm()和pause()函数alarm() 定时函数paus…

玩转传感器----理解时序和数据采集(DHT11)

该文章以DHT11模块进行分析 目录 1.模块复位&#xff08;时序图&#xff09; 2.DHT11的应答信号 3.读取1bit数值&#xff08;比较高电平的时间是否大于40us&#xff09; 4.读取一个字节 5.把读取的字节放入单片机 6. 寄存器设置IO口方向 1.模块复位&#xff08;时序图&a…

22.Java多线程

Java多线程 一、进程和线程 进程是程序的一次动态执行过程&#xff0c;它需要经历从代码加载&#xff0c;代码执行到执行完毕的一个完整的过程&#xff0c;这个过程也是进程本身从产生&#xff0c;发展到最终消亡的过程。多进程操作系统能同时达运行多个进程&#xff08;程序…

使用Python接口自动化测试post请求和get请求,获取请求返回值

目录 引言 请求接口为Post时&#xff0c;传参方法 获取接口请求响应数据 引言 我们在做python接口自动化测试时&#xff0c;接口的请求方法有get,post等&#xff1b;get和post请求传参&#xff0c;和获取接口响应数据的方法&#xff1b; 请求接口为Post时&#xff0c;传参方法…

C++系列二:数据类型

C数据类型 1. 原始类型2. 复合类型3. 类型转换3.1 隐式类型转换3.2 显式类型转换 4. 总结&#xff08;手稿版&#xff09; 1. 原始类型 C 中的原始类型包括整型&#xff08;integral types&#xff09;、浮点型&#xff08;floating-point types&#xff09;、字符型&#xff…

涨薪60%,从小厂逆袭,坐上美团技术专家(面经+心得)

前言 大多数情况下&#xff0c;程序员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 实际上&#xff0c;跳槽的目的无非是为了涨薪或是职业发展&#xff0c;我也不例外。普通本科毕业后&#xf…

计算机网络基础知识(一)计算机发展史、网络设备、网络结构及拓扑

文章目录 01 | 网络设备02 | 网络结构 && 拓扑 网络发展史可以追溯到20世纪60年代&#xff0c;当时美国国防部高级研究计划署&#xff08;ARPA&#xff09;启动了一个名为 ARPANET 的项目&#xff0c;旨在建立军事目的的分布式通信网络&#xff0c;使得网络中的任何一台…

【redis】redis红锁Redlock算法和底层源码分析

【redis】redis红锁Redlock算法和底层源码分析 文章目录 【redis】redis红锁Redlock算法和底层源码分析前言一、当前代码为8.0版&#xff0c;接上一步分布式锁的主要考点lock加锁关键逻辑unlock解锁关键逻辑 二、redis分布式锁-Redlock红锁主页说明:目前所写的分布式锁还有什么…

c++自学笔记(陆续更新)

本笔记为从菜鸟教程边学边记录的笔记---》C 教程 | 菜鸟教程 面向对象程序设计 封装&#xff08;Encapsulation&#xff09;&#xff1a;封装是将数据和方法组合在一起&#xff0c;对外部隐藏实现细节&#xff0c;只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。…

C语言入门教程||C语言 头文件||C语言 强制类型转换

C语言 头文件 头文件是扩展名为 .h 的文件&#xff0c;包含了 C 函数声明和宏定义&#xff0c;被多个源文件中引用共享。有两种类型的头文件&#xff1a;程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件&#xff0c;需要使用 C 预处理指令 #include 来引用它…

USART串口接收

文章目录 运行环境&#xff1a;1.1 串口接收代码分析1)开启接收中断和空闲中断2)接收存储变量声明和定义3)中断处理函数 2.1实验效果 运行环境&#xff1a; ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 usb转串口 杜邦线转4pin 1.1 串口接收…

Python | 人脸识别+活体检测+背景模糊+关键点检测系统(Face_Recognition+dlib+OpenCV+MediaPipe+PyQt)

本博客为人脸识别系统项目简介 项目GitHub完整源代码地址&#xff1a; 一、运行环境 本系统能够运行在基于PC操作系统Windows环境下&#xff0c;要求Windows操作系统安装Python 3.9 及以上环境&#xff0c;且已安装MySQL数据库。 Python3.9 安装&#xff1a;Python 3.9安装教程…

【UE】坦克开火

1. 添加开火的操作映射 2. 创建一个actor蓝图类&#xff0c;添加一个静态网格体组件 添加发射物移动组件 设置初始速度和最大速度 发射物重力范围设为0.05 添加音频组件 设置音效 3. 打开炮管的静态网格体 在插槽管理器中创建插槽 将创建的插槽放到炮口位置 4. 打开“BP_BaseT…

B-Tree (多路查找树)分析-20230503

B-Tree (多路查找树)学习-20230503 前言 B-树是一类多路查询树&#xff0c;它主要用于文件系统和某些数据库的索引&#xff0c;如果采用二叉平衡树访问文件里面的数据&#xff0c;最坏情况下&#xff0c;磁头可能需要进行O(h)次对磁盘的读写&#xff0c;其中h为树的高度&…