算法基础:高精度运算

简介: 算法基础:高精度运算

一、高精度加法:

算法模板:

vector<int> add(vector<int>&A,vector<int>&B)
{
    vector<int>C;
    int t=0;//进位
    for(int i=0;i<A.size()||i<B.size();i++)
    {
        if(i<A.size())t+=A[i];
        if(i<B.size())t+=B[i];
        C.push_back(t%10);
        t/=10;
    }
    if(t)C.push_back(1);
    return C;
}

例题:

给定两个正整数(不含前导 00),计算它们的和。

输入格式

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

输出格式

共一行,包含所求的和。

数据范围

1≤整数长度≤1000001≤整数长度≤100000

输入样例:

12
23

输出样例:

35
#include<iostream>
#include<vector>
 
using namespace std;
 
vector<int> add(vector<int>&A,vector<int>&B)
{
    vector<int>C;
    int t=0;//进位
    for(int i=0;i<A.size()||i<B.size();i++)
    {
        if(i<A.size())t+=A[i];
        if(i<B.size())t+=B[i];
        C.push_back(t%10);
        t/=10;
    }
    if(t)C.push_back(1);
    return C;
}
int main()
{
    string a,b;
    vector<int> A,B;
    //a=456342420298425631002819049046,b=42568245372799024844654500802
    cin>>a>>b;
    //A=[6,4,0,9,4,0,9,1,8,2,0,0,1,3,6,5,2,4,8,9,2,0,2,4,2,4,3,6,5,4,4]
    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
    //B=[2,0,8,0,0,5,4,5,6,4,4,8,4,,2,0,9,9,7,2,7,3,5,4,2,8,6,5,2,4]
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
    //C=[8,4,8,9,4,5,3,7,4,7,4,8,5,5,6,4,2,2,1,7,6,5,6,6,0,1,9,8,9,4]
    //C=[4,9,8,9,1,0,6,6,5,6,7,1,2,2,4,6,5,5,8,4,7,4,7,3,5,4,9,8,4,8]
    auto C=add(A,B);
    for(int i=C.size()-1;i>=0;i--)printf("%d",C[i]);
}

二、高精度减法:

思路:

和高精度加法差不多,值得注意的是

减法的借位处理

相减为负数的处理

前导0的处理

相减后t的处理 ,把 t >=0 和 t < 0 用一个式子来表示 t = (t + 10) % 10

算法模板:

A与B的判断:

bool cmp(vector<int>& A, vector<int> &B)
{
    if(A.size() != B.size()) return A.size() > B.size();  //直接ruturn 了就不用else
 
    for(int i = A.size(); i >= 0; i--)
        if(A[i] != B[i])
            return A[i] > B[i];
 
    return true;
}

减法模板:

vector<int> sub(vector<int>& A,vector<int>& B)
{ 
    vector<int>C;
    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); // 将t>0输出t和t<0输出t+10俩种情况合而为1
        if(t<0)t=1;
        else t=0;
    }
    while(C.size() > 1 && C.back() == 0) C.pop_back();  //去掉前导0
    return C;
}

例题:

给定两个正整数(不含前导 00),计算它们的差,计算结果可能为负数。

输入格式

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

输出格式

共一行,包含所求的差。

数据范围

1≤整数长度≤10^5

输入样例:

32
11

输出样例:

21
#include<iostream>
#include<vector>
 
using namespace std;
//判断是否有A>=B
bool cmp(vector<int>&A,vector<int>&B)
{
    if(A.size()!=B.size())return A.size()>B.size();//直接ruturn 了就不用else
    for(int i=A.size();i>=0;i--)
    {
        if(A[i]!=B[i])
            return A[i]>B[i];
    }
    return true;
}
 
vector<int> sub(vector<int>& A,vector<int>& B)
{ 
    vector<int>C;
    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); // 将t>0输出t和t<0输出t+10俩种情况合而为1
        if(t<0)t=1;
        else t=0;
    }
    while(C.size() > 1 && C.back() == 0) C.pop_back();  //去掉前导0
    return C;
}
 
 
int main()
{
    string a,b;
    vector<int>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))
    {
        auto C=sub(A,B);
        for(int i=C.size()-1;i>=0;i--)printf("%d",C[i]);
        return 0;
    }
    else
    {
         auto C=sub(B,A);
         cout<<"-";
         for(int i=C.size()-1;i>=0;i--)printf("%d",C[i]);
         return 0;
    }
    
    return 0;
}

三、高精度乘法

乘法模板:

vector<int>mul(vector<int>A,int b)
{
    int t=0;
    vector<int>C;
    for(int i=0;i<A.size();i++)
    {
        if(i<A.size())t+=A[i]*b;// t + A[i] * b = 7218
        C.push_back(t%10);// 只取个位 8
        t/=10; // 721 看作进位
    }
    while (t)// 处理最后剩余的 t
    {            
        C.push_back(t % 10);
        t /= 10;
    }
    //去掉前导0
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

例题:

给定两个非负整数(不含前导 00) A 和 B,请你计算 A×B 的值。

输入格式

共两行,第一行包含整数 A,第二行包含整数 B。

输出格式

共一行,包含 A×B 的值。

数据范围

1≤A的长度≤100000

0≤B≤100000

输入样例:

2
3

输出样例:

6
#include<iostream>
#include<vector>
 
using namespace std;
 
vector<int>mul(vector<int>A,int b)
{
    int t=0;
    vector<int>C;
    //与高精度加法思路相似
    for(int i=0;i<A.size();i++)
    {
        if(i<A.size())t+=A[i]*b;// t + A[i] * b = 7218
        C.push_back(t%10);// 只取个位 8
        t/=10; // 721 看作进位
    }
    while (t)// 处理最后剩余的 t
    {            
        C.push_back(t % 10);
        t /= 10;
    }
    //去掉前导0
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}
int main()
{
    string a;
    int b;
    vector<int>A;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
    auto C=mul(A,b);
    for(int i=C.size()-1;i>=0;i--)printf("%d",C[i]);
    return 0;
}

四、高精度除法

除法模板:

vector<int> div(vector<int> &A,int B,int &r)
{
    vector<int> C;
    for(int i=0;i<A.size();i++)
    {
        r=r*10+A[i];
        C.push_back(r/B);
        r=r%B;
    }
    reverse(C.begin(),C.end());
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}

例题:

给定两个非负整数(不含前导 00) A,B请你计算 A/B的商和余数。

输入格式

共两行,第一行包含整数 A,第二行包含整数 B。

输出格式

共两行,第一行输出所求的商,第二行输出所求余数。

数据范围

1≤A的长度≤100000

1≤B≤10000

B 一定不为 0

输入样例:

7
2

输出样例:

3
1
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
//int r=0;
vector<int> div(vector<int> &A,int B,int &r)
{//r传入r的地址,便于直接对余数r进行修改
    vector<int> C;
    for(int i=0;i<A.size();i++)
    {//对A从最高位开始处理
        r=r*10+A[i];//将上次的余数*10在加上当前位的数字,便是该位需要除的被除数
        C.push_back(r/B);//所得即为商在这一位的数字
        r=r%B;
    }
    //由于在除法运算中,高位到低位运算,因此C的前导零都在vector的前面而不是尾部,vector只有删除最后一个数字pop_back是常数复杂度,而对于删除第一位没有相应的库函数可以使用,而且删除第一位,其余位也要前移,
    //因此我们将C翻转,这样0就位于数组尾部,可以使用pop函数删除前导0
    reverse(C.begin(),C.end());
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}
int main()
{
    string a;
    int B,r=0; //代表余数
    cin>>a>>B;
    vector<int> A;
    for(int i=0;i<a.size();i++) A.push_back(a[i]-'0');//注意这次的A是由高为传输至低位,由于    在除法的手算过程中,发现从高位进行处理
    //for(int i=0;i<A.size();i++) cout<<A[i];
    //cout<<B;
    auto C = div(A,B,r);
    for(int i=C.size()-1;i>=0;i--) cout<<C[i];//将C从最高位传给最低位
    cout<<endl<<r;//输出余数
    cout<<endl;
 
    return 0;
}


目录
相关文章
|
8天前
|
算法 Java
Java数据结构与算法:位运算之与、或、异或运算
Java数据结构与算法:位运算之与、或、异或运算
|
26天前
|
算法
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
17 0
|
2月前
|
算法 C++
c++算法学习笔记 (4)高精度运算
c++算法学习笔记 (4)高精度运算
|
2月前
|
人工智能 算法 BI
【算法基础】基础算法(二)--(高精度、前缀和、差分)(下)
【算法基础】基础算法(二)--(高精度、前缀和、差分)(下)
|
2月前
|
存储 算法 索引
【算法基础】基础算法(二)--(高精度、前缀和、差分)(上)
【算法基础】基础算法(二)--(高精度、前缀和、差分)(上)
|
2月前
|
算法 Java C++
试题 算法训练 集合运算
试题 算法训练 集合运算
21 1
|
8月前
|
存储 算法
【算法基础】高精度运算
【算法基础】高精度运算
33 0
|
8月前
|
存储 人工智能 算法
C++基础算法高精度篇
C++基础算法高精度篇
|
9月前
|
算法 搜索推荐 C++
【C++STL基础入门】vector运算和遍历、排序、乱序算法
【C++STL基础入门】vector运算和遍历、排序、乱序算法
120 0
|
算法 Python
算法创作|用python解决简单的数学运算
算法创作|用python解决简单的数学运算
69 0