【算法总结】数学问题-高精度整数

【算法总结】高精度整数

我们首先明确高精度整数的保存形式,我们常用如下结构体来保存一个高精度整数

struct biginteger
{
    int digit[1000];//保存大整数中若干位的数字,暂且使用每4位为一个单位保存
    int size;//size是digit数组中第一个我们还未使用的数组单元,即digit数组下一个存储单元的角标
};

一、高精度加法

例 4.11 a+b

AC代码

#include<cstdio>
#include<cstring>

struct biginteger//高精度整数结构体
{
    int digit[1000];//保存大整数中若干位的数字,暂且使用每4位为一个单位保存
    int size;//size是digit数组中第一个我们还未使用的数组单元,即digit数组下一个存储单元的角标
    void init()//对结构体的初始化
    {
        for (int i = 0; i < 1000; i++)digit[i] = 0;//所有数位清0
        size = 0;//没有一个单元被使用
    }
    void set(char str[])//从字符串中提取整数存入大数数组,单元内顺序,单元外倒序存储
    {
        init();//对结构体的初始化
        int L = strlen(str);//计算字符串长度
        for (int i = L - 1, j = 0, t = 0, c = 1; i >= 0; i--)//从最后一个字符开始倒序遍历字符串,j控制每4个字符转换为一个数字存入数组,t临时保存字符转换为数字的中间值,c表示当前位的权重,按1,10,100,1000变化
        {
            t += (str[i] - '0')*c;//计算四位数中当前字符代表的数值
            j++;//数位增加
            c *= 10;//权重更新
            if (j == 4 || i == 0)//若已经连续转换4个字符,或者已到达最后一个字符
            {
                digit[size++] = t;//将这四个字符代表的四位数存入数组,size移动到下一个单位
                j = 0;//更新
                t = 0;//更新
                c = 1;//更新
            }
        }
    }
    void output()//将该高精度整数输出
    {
        for (int i = size - 1; i >= 0; i--)
        {
            if (i != size - 1)printf("%04d", digit[i]);//不是最高位则当前数组不足4位时用0补充
            else printf("%d", digit[i]);//最高位不用补充0
        }
        printf("\n");
    }
    biginteger operator + (const biginteger &A)const//重载加法运算符
    {
        biginteger ret;//返回值,两数相加的结果
        ret.init();//初始化
        int carry = 0;//进位,初始值为0
        for (int i = 0; i < A.size || i < size; i++)
        {
            int tmp = A.digit[i] + digit[i] + carry;//计算两个整数当前位以及来自低位的进位和
            carry = tmp / 10000;//计算该位的进位
            tmp %= 10000;//去掉进位部分
            ret.digit[ret.size++] = tmp;//保存该位结果
        }
        if (carry != 0) ret.digit[ret.size++] = carry;//最高位的进位
        return ret;
    }
}a, b, c;//结构体别名

char str1[1002], str2[1002];

int main()
{
    while (scanf("%s%s", str1, str2) != EOF)
    {
        a.set(str1);
        b.set(str2);
        c = a + b;
        c.output();
    }
    return 0;
}

二、高精度乘法

这里指的乘法运算一般为高精度整数乘以一般小整数的运算。

例4.12 N的阶乘

AC代码

#include<cstdio>
#include<cstring>

struct biginteger//高精度整数结构体
{
    int digit[1000];//保存大整数中若干位的数字,暂且使用每4位为一个单位保存
    int size;//size是digit数组中第一个我们还未使用的数组单元,即digit数组下一个存储单元的角标
    void init()//对结构体的初始化
    {
        for (int i = 0; i < 1000; i++)digit[i] = 0;//所有数位清0
        size = 0;//没有一个单元被使用
    }
    void set(int x)
    {
        init();//对结构体的初始化
        do//对一个小整数4位一个单位分解依次存入digit中
        {
            digit[size++] = x % 10000;
            x /= 10000;
        } while (x != 0);
    }
    void output()//将该高精度整数输出
    {
        for (int i = size - 1; i >= 0; i--)
        {
            if (i != size - 1)printf("%04d", digit[i]);//不是最高位则当前数组不足4位时用0补充
            else printf("%d", digit[i]);//最高位不用补充0
        }
        printf("\n");
    }
    biginteger operator * (int x)const//重载加法运算符
    {
        biginteger ret;//返回值
        ret.init();//初始化
        int carry = 0;//进位,初始值为0
        for (int i = 0; i < size; i++)
        {
            int tmp = x * digit[i] + carry;//计算小整数乘以当前位数字来自低位的进位和
            carry = tmp / 10000;//计算该位的进位
            tmp %= 10000;//去掉进位部分
            ret.digit[ret.size++] = tmp;//保存该位结果
        }
        if (carry != 0) ret.digit[ret.size++] = carry;//最高位的进位
        return ret;
    }
}a;//结构体别名

char str1[1002], str2[1002];

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        a.init();
        a.set(1);//a的初始值为1
        for (int i = 1; i <= n; i++)
        {
            a = a * i;
        }
        a.output();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yun-an/p/11075064.html