高精度算法

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 本文详细介绍了高精度算法的实现,涵盖加法、减法、乘法、除法及取模等操作。通过字符串与数组结合的方式,解决了大数运算中超出数据类型范围的问题。每种运算均提供完整的C++代码示例,包括输入处理、位运算模拟、进位/借位逻辑以及结果输出。其中,高精度加法和减法通过逆序存储数字简化计算;乘法利用双重循环模拟手算过程;除法分为低精度和高精度两种情况,分别采用逐位试商与减法模拟;取模则通过逐位累加求余实现。这些方法为处理大规模数值运算提供了有效工具,适用于竞赛编程与实际开发场景。

高精度算法

作者:blue

时间:2024.9

1.高精度加法(整数部分模板)

#include <iostream>
#include <string>
using namespace std;
int a1[1000],a2[1000],ans[1000];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;//字符串存放大数
    //逆序存放在数组中 
    for(int i=0;i<s1.size();i++) a1[s1.size()-i-1]=s1[i]-'0';
    for(int i=0;i<s2.size();i++) a2[s2.size()-i-1]=s2[i]-'0';
    int len=max(s1.size(),s2.size());
    //先相加 
    for(int i=0;i<len;i++){
   
        ans[i]=a1[i]+a2[i];
    }
    //后处理进位 
    for(int i=0;i<len;i++){
   
        ans[i+1]=ans[i+1]+ans[i]/10;
        ans[i]=ans[i]%10;
    }
    //逆序输出先判断len位为不为0(因为最高位可能进位,所以最长到len位)
    for(int i=len;i>=0;i--){
   
        if(i==len&&ans[len]==0) continue;
        cout<<ans[i];
    }
    return 0;
}

2.高精度减法(整数部分模板)

#include <iostream>
#include <string>
using namespace std;
const int N=1e6+10;
int a1[N],a2[N],ans[N];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;
    char flag='+';//符号判断 
    //判断两个数谁大谁小,大的那个放置在s1,如果交换了位置,就将符号置为'-'
    if(s1.size()<s2.size()||s1.size()==s2.size()&&s1<s2){
   
        swap(s1,s2);
        flag='-';
    } 
    //倒序存放 
    for(int i=0;i<s1.size();i++) a1[i]=s1[s1.size()-i-1]-'0';
    for(int i=0;i<s2.size();i++) a2[i]=s2[s2.size()-i-1]-'0';
    for(int i=0;i<s1.size();i++){
   
        if(a1[i]<a2[i]){
   //模拟借位的过程 
            a1[i]+=10;
            a1[i+1]--;
        }
        ans[i]=a1[i]-a2[i];
    }
    //注意此处index的值设置为0是有考究的,当是两个相等大数相减的话,那就只用输出1位0 
    int index=0;//找答案中第一个不为0的位置,为输出做准备 
    for(int i=s1.size()-1;i>=0;i--){
   
        if(ans[i]>0){
   
            index=i;
            break;
        }
    } 
    if(flag=='-') cout<<flag;
    for(int i=index;i>=0;i--) cout<<ans[i];
    return 0;
}

3.高精度乘法

image-20241019090817352.png

#include <iostream>
#include <string>
using namespace std;
const int N=1e8+10;
int a1[N],a2[N],ans[N];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;
    //反转两个数 
    for(int i=0;i<s1.size();i++) a1[i]=s1[s1.size()-i-1]-'0'; 
    for(int i=0;i<s2.size();i++) a2[i]=s2[s2.size()-i-1]-'0'; 
    int len=s1.size()+s2.size();//乘法最终的长度不会长于两个常数长度的和 
    //模拟乘法过程
    for(int i=0;i<s1.size();i++){
   
        for(int j=0;j<s2.size();j++){
   
            ans[i+j]+=a1[i]*a2[j];//注意这里不是赋值语句 
            ans[i+j+1]+=ans[i+j]/10;//进位 
            ans[i+j]=ans[i+j]%10;//保留本位 
        }
    } 
    //消除前导0 
    int index=0;
    for(int i=len;i>=0;i--){
   
        if(ans[i]!=0){
   
            index=i;
            break;
        }
    }
    //倒序输出 
    for(int i=index;i>=0;i--){
   
        cout<<ans[i];
    }
    return 0;
}

4.高精度除法

高精度除以低精度

image-20241019092848282.png

#include <iostream>
#include <string>
using namespace std;
const int N=1e8+10;
int ans[N],a[N];
long long b;
int main()
{
   
    string s;
    long long x=0;//用以承接每次的余数,初始应当为0,因为没有余数,注意这里余数也要开long long 防止余数很大的情况 
    cin>>s>>b;//输入一个高精度数和一个低精度数
    //这里不用倒序存放,因为除法本身就是一个从高位计算到低位的过程 
    for(int i=0;i<s.size();i++) a[i]=s[i]-'0';
    //模拟逐位试商的过程 
    for(int i=0;i<s.size();i++){
   
        ans[i]=(x*10+a[i])/b;
        x=(x*10+a[i])%b;
    }
    int index=0;
    //消除前导0,注意此处,index不能超过被除数的长度 
    while(ans[index]==0&&index<s.size()) index++;
    for(int i=index;i<s.size();i++) cout<<ans[i];
    if(index==s.size()) cout<<"0";//如果index等于被除数的长度,那么说明商就为0,要打印0
    //cout<<" "<<x;//有需要还可以打印余数 
    return 0;
}

高精度除以高精度

高精度除高精度要用减法模拟除法

image-20241019145033990.png

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
const int N=1e6+10;
int a[N],b[N],c[N],tmp[N];
void init(int a[]){
   
    string s;
    cin>>s;
    a[0]=s.size();//a[0]存储字符串的长度 
    for(int i=1;i<=s.size();i++) a[i]=s[s.size()-i]-'0';//逆序存储 
}
void print(int a[]){
   
    if(a[0]==0){
   
        cout<<"0";
        return;
    }
    for(int i=a[0];i>0;i--) cout<<a[i];
    return;
}
int compare(int a[],int b[]){
   //比较两个数的大小,如果a大返回1,如果b大返回-1,一样大返回0 
    if(a[0]>b[0]) return 1;
    if(a[0]<b[0]) return -1;
    for(int i=a[0];i>0;i--){
   
        if(a[i]>b[i]) return 1;
        if(a[i]<b[i]) return -1; 
    }
    return 0;
}
void minu(int a[],int b[]){
   //高精度减法 
    for(int i=1;i<=a[0];i++)
    {
   
        if(a[i]<b[i]){
   
            a[i]+=10;
            a[i+1]--;
        }
        a[i]=a[i]-b[i];
    }
    while(a[a[0]]==0&&a[0]>0) a[0]--;//删除前导0 
    return; 
}
void numcpy(int b[],int tmp[],int n){
   //
    for(int i=1;i<=b[0];i++) tmp[i+n]=b[i];
    tmp[0]=b[0]+n;
}
int main()
{
   
    init(a);
    init(b);
    c[0]=a[0]-b[0]+1;//两位数相除,商最长的长度 
    if(c[0]<0) c[0]=0;
    for(int i=c[0];i>=1;i--){
   
        memset(tmp,0,sizeof(tmp));
        numcpy(b,tmp,i-1);//减法模拟除法,扩展减数,和被减数一样长 
        while(compare(a,tmp)>=0){
   //减干净 
            c[i]++;
            minu(a,tmp);
        }
    }
    while(c[c[0]]==0&&c[0]>0) c[0]--;//消去前导0 
    print(c);
    //print(a);//余数 
}

5.高精度取模

蛐蛐取mod,直接拿下

4.字符串加法【算法赛】 - 蓝桥云课 (lanqiao.cn)

#include <iostream>
#include <string>
#define int long long
using namespace std;
const int mod=1e9+7;
long long long_mod(string a)
{
   
  int ans=0;
  for(int i=0;i<a.size();i++){
   
    ans=(ans*10+(a[i]-'0'))%mod;
  }
  return ans;
}

signed main()
{
   
  string a,b,res;
  cin>>a>>b;
  res=a+b;
  cout<<long_mod(res);
  return 0;
}

6.高精度

第十五届蓝桥杯C/C++B组题解——R格式_第十五届蓝桥杯c语言b组答案-CSDN博客

目录
相关文章
|
消息中间件 存储 NoSQL
深入Redis消息队列:Pub/Sub和Stream的对决【redis第六部分】
深入Redis消息队列:Pub/Sub和Stream的对决【redis第六部分】
1348 0
|
存储 Shell 网络安全
|
弹性计算 Linux 数据库
快速用Discuz搭建论坛网站教程
Discuz! 是全球成熟度最高、覆盖率最大的论坛网站软件系统之一,被200多万网站用户使用,本文教你一步一步快速用阿里云免费的Discuz官方系统搭建论坛网站。
45824 0
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
4032 0
高精度算法(加、减、乘、除,使用c++实现)
|
11月前
|
机器学习/深度学习 算法 数据可视化
基于YOLOv8的无人机航拍树木目标检测系统|精准识别【含完整训练源码+部署教程】
本项目基于YOLOv8构建了一个支持无人机航拍图像的棕榈树目标检测系统,兼具高精度识别能力与友好的图形化交互界面。通过结合PyQt5,实现了图片、视频、摄像头等多种输入方式的检测体验,极大提升了项目的实用性与可扩展性。
基于YOLOv8的无人机航拍树木目标检测系统|精准识别【含完整训练源码+部署教程】
|
存储
【洛谷 P1255】数楼梯 题解(递归+记忆化搜索+高精度)
这是一个使用动态规划解决的“数楼梯”问题。给定楼梯数`N`,求不同上楼方式的数量。程序通过递归函数`f()`计算,其中`f(x) = f(x - 1) + f(x - 2)`,初始条件`f(1) = 1`,`f(2) = 2`。考虑到数据规模可能很大,使用了高精度加法运算。样例输入`4`,输出`5`。代码中定义了一个存储中间结果的向量`mem`,并提供了一个用于显示高精度数的`printv()`函数。
494 0
|
算法 编译器 C++
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
【狂热算法篇】探秘图论之Dijkstra 算法:穿越图的迷宫的最短路径力量(通俗易懂版)
|
数据采集 Web App开发 前端开发
Python爬虫进阶:Selenium在动态网页抓取中的实战
【10月更文挑战第26天】动态网页抓取是网络爬虫的难点,因为数据通常通过JavaScript异步加载。Selenium通过模拟浏览器行为,可以加载和执行JavaScript,从而获取动态网页的完整内容。本文通过实战案例,介绍如何使用Selenium在Python中抓取动态网页。首先安装Selenium库和浏览器驱动,然后通过示例代码展示如何抓取英国国家美术馆的图片信息。
1119 6
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
496 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)

热门文章

最新文章