学习思路

高精度是算法里面不常考的题目,但是掌握高精度也更有利于我们学习算法和解决实际开发中所遇到的问题,我们知道int的数据范围是-2^31~2^31-1,而long long 的数据范围是-2^63~2^63-1,那么当一个数超过了long long 的范围,想要计算它的结果就变得十分困难,为此我们转变思路,可以利用字符串数组存储那个数,再通过字符串数组个位转整型数字的方式进行人类熟悉的四则运算,最后再将得到的结果用另一个字符串数组存储起来,字符串数组的范围是无限的,根据计算机的内存进行扩充,计算机的内存有多大就可以存储多大的字符串,这便是高精度算法的思想。

高精度加法模板:(高精+高精)

原题链接

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string addfun(string a, string b)
{
    string c;
    int t = 0;
    for (int i = a.size() - 1, j = b.size() - 1; i >= 0 || j >= 0 || t > 0; --i, --j)
    {
        if (i >= 0)
        {
            t += (a[i] - '0'); //通过减去字符 '0' 可以将一个数字字符转变成可以参与运算的整型数字
        }
        if (j >= 0)
        {
            t += (b[j] - '0');
        }
        c += ((t % 10) + '0'); //通过加上字符 '0' 可以将参与运算后的整型数字重新转变回数字字符,存放进字符串数组中
        t /= 10;
    }
    reverse(c.begin(), c.end()); //因为是从字符串末位一个一个往前倒着运算的,所以最后得到的结果要进行翻转
    return c;
}
int main()
{
    //使C++输入输出流变快
    ios::sync_with_stdio(false);
    string a, b;
    cin >> a >> b;
    cout << addfun(a, b) << endl;
    return 0;
}

高精度减法模板:(高精-高精)

原题链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
bool cmp(string a, string b)
{
    if (a.size() != b.size())
    {
        return a.size() > b.size();
    }
    for (int i = 0; i < a.size(); ++i)
    {
        if (a[i] != b[i])
        {
            return a[i] > b[i];
        }
    }
    return true;
}
string subfun(string a, string b)
{
    string c;
    int t = 0;
    for (int i = a.size() - 1, j = b.size() - 1; i >= 0 || j >= 0 || t > 0; --i, --j)
    {
        if (i >= 0)
        {
            t = (a[i] - '0') - t; //通过减去字符 '0' 可以将一个数字字符转变成可以参与运算的整型数字
        }
        if (j >= 0)
        {
            t -= (b[j] - '0');
        }
        c += ((t + 10) % 10 + '0'); //通过加上字符 '0' 可以将参与运算后的整型数字重新转变回数字字符,存放进字符串数组中
        if (t < 0)
        {
            t = 1;
        }
        else
        {
            t = 0;
        }
    }
    while (c.size() > 1 && c.back() == '0') //去掉字符串末尾的0
    {
        c.pop_back();
    }
    reverse(c.begin(), c.end()); //因为是从字符串末位一个一个往前倒着运算的,所以最后得到的结果要进行翻转
    return c;
}
int main()
{
    //使C++输入输出流变快
    ios::sync_with_stdio(false);
    string a, b;
    cin >> a >> b;
    if (cmp(a, b)) //判断有没有可能第一个数比第二个数小,减成负数的情况
    {
        cout << subfun(a, b) << endl;
    }
    else
    {
        cout << "-" << subfun(b, a) << endl; //如果会减成负数那么就要在前面加上负号
    }
    return 0;
}

高精度乘法模板:(高精*低精)

原题链接

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
string mulfun(string a,int b)
{
    string c;
    int t=0;
    for(int i=a.size()-1;i>=0||t>0;--i)
    {
        if(i>=0)
        {
            t+=(a[i]-'0')*b; //通过减去字符 '0' 可以将一个数字字符转变成可以参与运算的整型数字
        }
        c+=((t%10)+'0'); //通过加上字符 '0' 可以将参与运算后的整型数字重新转变回数字字符,存放进字符串数组中
        t/=10;
    }
    reverse(c.begin(),c.end()); //因为是从字符串末位一个一个往前倒着运算的,所以最后得到的结果要进行翻转
    return c;
}
int main()
{
    //使C++输入输出流变快
    ios::sync_with_stdio(false);
    string a;
    int b;
    cin>>a>>b;
    if(a=="0"||b==0) //因为0乘任何数都得0,所以两个数只要有一个是0就不用参与后面的运算了
    {
        cout<<0<<endl;
    }
    else
    {
        cout<<mulfun(a,b)<<endl;
    }
    return 0;
}

高精度除法模板:(高精/低精)

原题链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
string divfun(string a,int b,int &r)
{
    string c;
    for(int i=0;i<a.size();++i)
    {
        r=r*10+(a[i]-'0'); //通过减去字符 '0' 可以将一个数字字符转变成可以参与运算的整型数字
        c+=((r/b)+'0'); //通过加上字符 '0' 可以将参与运算后的整型数字重新转变回数字字符,存放进字符串数组中
        r%=b;
    }
    while(c.size()>1&&c.front()=='0') //去掉字符串首位的0
    {
        c = c.substr(1);
    }
    return c;
}
int main()
{
    //使C++输入输出流变快
    ios::sync_with_stdio(false);
    string a;
    int b;
    cin>>a>>b;
    int r = 0;
    cout<<divfun(a,b,r)<<endl;
    cout<<r<<endl;
    return 0;
}