zoukankan      html  css  js  c++  java
  • 【算法总结】数学问题-高精度整数

    【算法总结】高精度整数

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

    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("
    ");
        }
        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("
    ");
        }
        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;
    }
  • 相关阅读:
    三分钟学会funsioncharts
    funsioncharts的图表操作heatmap
    FunsionCharts图标控件点击
    微信小程序组件解读和分析:二、scrollview可滚动视图区域 微信开发
    微信小程序组件解读和分析:五、text文本 微信开发
    微信小程序组件解读和分析:三、swiper滑块视图 微信开发
    微信小程序组件解读和分析:四、icon图标 微信开发
    asp.net 判断上传文件的类型
    C#序列化(Serialize)、反序列化(Deserialize)
    [置顶] http://www.openlib.com 一个神奇的网站
  • 原文地址:https://www.cnblogs.com/yun-an/p/11075064.html
Copyright © 2011-2022 走看看