高精度运算

简介: 复习acwing算法基础课的内容,本篇为讲解基础算法:高精度运算,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上

文章目录

前言

一、高精度运算概述

二、高精度算法

1. 高精度加法

AcWing791. 高精度加法

高精度加法模板

AC代码

2.高精度减法

AcWing 792. 高精度减法

高精度减法模板

AC代码

3.高精度乘法

AcWing 793. 高精度乘法

高精度乘法模板

AC代码

4.高精度除法

AcWing 794. 高精度除法

高精度除法模板

AC代码

三、时间复杂度

前言

复习acwing算法基础课的内容,本篇为讲解基础算法:高精度运算,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上


一、高精度运算概述

我们都知道,我们定义一个数,不论是整数还是浮点数,它都是有范围的都是有限的,就拿unsigned long long为例,它的最大值也就1e19,意思是最多只有19位,而我们想要进行40位,50位甚至更多位数的运算,显然就不能简单的定义int,long long等类型进行计算了,这时候我们就可以运用到高精度算法,把每一位上的数都存到数组之中,本博客的高精度算法中,用到了STL中的vector,关于vector,详见:vector


二、高精度算法

1. 高精度加法

AcWing791. 高精度加法

本题链接:AcWing791. 高精度加法

本博客给出题目截图:

image.png

高精度加法模板

本模板来自ACWing算法基础课

vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);      //保证A的长度始终 ≥ B的长度,因为下面的for循环是通过遍历A的每个元素
    vector<int> C;
    //C中存储的就是A + B后的结果
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(t);                          //有可能最高位加法存在进位,如果t存在,就加入到C
    return C;
}
vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);      //保证A的长度始终 ≥ B的长度,因为下面的for循环是通过遍历A的每个元素
    vector<int> C;
    //C中存储的就是A + B后的结果
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(t);                          //有可能最高位加法存在进位,如果t存在,就加入到C
    return C;
}

AC代码

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
vector <int> A, B, C;
void add(vector <int> &A, vector <int> &B)
{
    if (A.size() < B.size()) add (B, A);
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(t);
}
int main()
{
    string a, b;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');    //a[i] - '0',就把char类型的数字变成了int类型的a[i]
    for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
    add(A, B);
    for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]);
    return 0;
}

2.高精度减法

AcWing 792. 高精度减法

本题链接:AcWing 792. 高精度减法

本博客给出题目截图:

image.png

高精度减法模板

本模板来自ACWing算法基础课

// C = A - B, 满足A >= B, A >= 0, B >= 0
vector<int> sub(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);        //因为t可能是负的
        //举个例子,我们计算10 - 8,对于个位而言就是-8,我们通过(t + 10) % 10的方法就可以得到2
        if (t < 0) t = 1;                  //证明存在借位,即像高位借1
        else t = 0;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();   //去除前导0
    //比如111111118 - 111111117 = 000000001,而我们要输出1,通过这一步骤可以实现,要求C.size() > 1是因为有可能答案就是0
    return C;
}

AC代码

保证始终是绝对值大的数去减绝对值小的数:

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
vector <int> A, B, C;
bool cmp(vector <int> &A, vector <int> &B)                 //比较A和B谁大
{
    if (A.size() != B.size()) return A.size() > B.size();
    else 
    {
        for (int i = A.size() - 1; i >= 0; i -- )
            if (A[i] != B[i]) return A[i] > B[i];
    }
    return true;
}
void sub(vector <int> &A, vector <int> &B)
{
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);            
        if (t < 0) t = 1;
        else t = 0;
    }    
    while (C.size() > 1 && C.back() == 0) C.pop_back();
}
int main()
{
    string a, b;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
    if (cmp(A, B)) sub (A, B);
    else
    {
        sub (B, A);
        printf("-");
    }
    for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
    return 0;
}

3.高精度乘法

AcWing 793. 高精度乘法

本题链接:AcWing 793. 高精度乘法

本博客给出题目截图:

image.png

高精度乘法模板

本模板来自ACWing算法基础课

vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();   //去除前导0
  //比如 123 * 0,按照这个运算的话是 0000,答案是0,故需要去除前导0
    return C;
}

AC代码

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
vector <int> A, B;
void mul(vector <int> &A, int b)
{
    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        t += A[i] * b;
        B.push_back(t % 10);
        t /= 10;
    }
    while (B.size() > 1 && B.back() == 0) B.pop_back();
}
int main()
{
    string a;
    int b;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
    mul(A, b);
    for (int i = B.size() - 1; i >= 0; i -- ) cout << B[i];
    return 0;
}

4.高精度除法

AcWing 794. 高精度除法

本题链接:AcWing 794. 高精度除法

本博客给出本题截图:

image.png

高精度除法模板

本模板来自ACWing算法基础课

vector<int> div(vector<int> &A, int b, int &r)    //传入的是r的地址,所以可以直接对r的值进行修改
{
    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());               
    //除法和加法,减法,乘法运算都不一样的是除法运算是高位向低位进行,而其他三种运算是从低位到高位运算
    //所以除法运算的前导0其实是在开头而不是尾部,而我们只能从尾部删除一个元素,所以我们要把C翻转
    while (C.size() > 1 && C.back() == 0) C.pop_back();   //去除前导0
    return C;
}

AC代码

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
vector <int> A, C;
int r;
void div(vector <int> A, int b)
{
    for (int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse (C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
}
int main()
{
    string a;
    int b;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
    div(A, b);
    for (int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
    cout << endl << r;
    return 0;
}

三、时间复杂度

关于高精度算法的时间复杂度以及证明,后续会给出详细的说明以及证明过程,目前先鸽了。

目录
相关文章
|
15天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
19天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
10天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
|
23天前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
9天前
|
人工智能 自然语言处理 前端开发
什么?!通义千问也可以在线开发应用了?!
阿里巴巴推出的通义千问,是一个超大规模语言模型,旨在高效处理信息和生成创意内容。它不仅能在创意文案、办公助理、学习助手等领域提供丰富交互体验,还支持定制化解决方案。近日,通义千问推出代码模式,基于Qwen2.5-Coder模型,用户即使不懂编程也能用自然语言生成应用,如个人简历、2048小游戏等。该模式通过预置模板和灵活的自定义选项,极大简化了应用开发过程,助力用户快速实现创意。
|
5天前
|
云安全 存储 弹性计算
|
7天前
|
云安全 人工智能 自然语言处理
|
5天前
|
人工智能 C++ iOS开发
ollama + qwen2.5-coder + VS Code + Continue 实现本地AI 辅助写代码
本文介绍在Apple M4 MacOS环境下搭建Ollama和qwen2.5-coder模型的过程。首先通过官网或Brew安装Ollama,然后下载qwen2.5-coder模型,可通过终端命令`ollama run qwen2.5-coder`启动模型进行测试。最后,在VS Code中安装Continue插件,并配置qwen2.5-coder模型用于代码开发辅助。
395 4
|
5天前
|
缓存 Linux Docker
【最新版正确姿势】Docker安装教程(简单几步即可完成)
之前的老版本Docker安装教程已经发生了变化,本文分享了Docker最新版安装教程,其他操作系统版本也可以参考官 方的其他安装版本文档。
【最新版正确姿势】Docker安装教程(简单几步即可完成)
|
11天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。