zoukankan      html  css  js  c++  java
  • 高精度算法

    所谓高精度算法,就是把一个大整数的每一位分开储存,分开操作,从而避免溢出。在某些时候,数据可能会大到long long类型都会溢出,这时候就需要用到高精度算法了。其实,高精度算法是比较鸡肋的,很少单独考察,而且通常会被模运算替代,使用次数越来越少。但不排除有些题目就是要用到高精度,比如NOIP2012 国王游戏,而且学习高精度算法可以加深对于加减乘除等基本运算的细节理解,也可以提升一下代码能力。

      1 #include <cstring>
      2 #include <iostream>
      3 #include <string>
      4 
      5 using namespace std;
      6 
      7 struct BigInteger {
      8     int num[maxn], len, flag; //flag用来表示是否为负数
      9 
     10     BigInteger(long long x = 0) {
     11         memset(num, 0, sizoef(num)); //切记要初始化!!!
     12         len = flag = 0;
     13         for (int i = 1; x; ++i)
     14             num[i] = x % 10, x /= 10, ++len;
     15     }
     16 
     17     BigInteger(string s = "0") {
     18         memset(num, 0, sizeof(num)); //切记要初始化!
     19         len = s.length(), flag = 0;
     20         for (int i = 1; i <= len; ++i)
     21             num[i] = s[len - i] - '0'; //不要忘记减去'0'
     22     }
     23 
     24     bool operator < (const BigInteger& rhs) const {
     25         if (len == rhs.len) { //小于运算符可将其他比较运算符表示出来
     26             for (int i = len; i >= 1; --i)
     27                 if (num[i] != rhs.num[i])
     28                     return num[i] < rhs.num[i];
     29             return false;
     30         }
     31         else return len < rhs.len;
     32     }
     33 
     34     void operator + (const BigInteger& rhs) {
     35         len = max(len, rhs.len);
     36         for (int i = 1; i <= len; ++i) {
     37             num[i] += rhs.num[i];
     38             if (num[i] > 9) { //加法进位
     39                 ++num[i + 1];
     40                 num[i] -= 10;
     41             }
     42         }
     43         if (num[len + 1]) ++len; //更新大整数的位数
     44     }
     45 
     46     void operator - (BigInteger& rhs) {
     47         if (*this < rhs)
     48             swap(*this, rhs), flag = 1; //保证被减数大于减数
     49         for (int i = 1; i <= len; ++i) {
     50             num[i] -= rhs.num[i];
     51             if (num[i] < 0) { //减法借位
     52                 --num[i + 1];
     53                 num[i] += 10;
     54             }
     55         }
     56         while (!num[len] && len > 1)
     57             --len; //更新位数,注意要加上len>1,否则为0时会出错
     58     }
     59 
     60     void operator * (const int& rhs) { //高精乘低精
     61         for (int i = 1; i <= len; ++i)
     62             num[i] *= rhs; //先每位乘上再处理进位
     63         for (int i = 1; i <= len; ++i)
     64             for (int j = i; num[j] > 9; ++j) {
     65                 num[j + 1] += num[j] / 10;
     66                 num[j] %= 10;
     67             }
     68         len += 15; //因为新增加的位数不超过15
     69         while (!num[len] && len > 1) --len;
     70     }
     71 
     72     void operator * (const BigInteger& rhs) { //高精乘高精
     73         BigInteger ans = BigInteger(0);
     74         for (int i = 1; i <= len; ++i) //列成竖式再观察,会有此规律
     75             for (int j = 1; j <= rhs.len; ++j) {
     76                 ans.num[i + j - 1] += num[i] * rhs.num[j];
     77                 if (ans.num[i + j - 1] > 9) {
     78                     ans.num[i + j] += ans.num[i + j - 1]/10;
     79                     ans.num[i + j - 1] %= 10;
     80                 }
     81             }
     82         ans.len = len + rhs.len;
     83         //一个a位数和一个b位数相乘,结果最多为a+b位数
     84         while (!ans.num[ans.len] && ans.len > 1) --ans.len;
     85         *this = ans;
     86     }
     87 
     88     void operator / (const int& rhs) { //高精除以低精
     89         for (int i = len; i >= 1; --i) {
     90             num[i - 1] += num[i] % rhs * 10;
     91             num[i] /= rhs;
     92         }
     93         num[0] /= 10; //num[0]保存余数
     94         while (!num[len] && len > 1) --len;
     95     }
     96 
     97     BigInteger operator / (BigInteger& rhs) { //高精除以高精
     98         BigInteger ans = BigInteger(0);
     99         //返回商,原来的BigInteger保存余数
    100         while (!(*this < rhs)) { //连续的减法模拟除法
    101             *this - rhs;
    102             ans + BigInteger("1");
    103         }
    104         return ans;
    105     }
    106 
    107     void print() {
    108         if (flag) cout << "-";
    109         for (int i = len; i >= 1;--i) cout << num[i];
    110     }
    111 };
  • 相关阅读:
    基于WINCE嵌入式系统的FM1702的读写器(2)
    WINCE 按键驱动编写
    WinCE内存调整
    USB模块
    网络模块
    wince6.0下ov9650的图像保存
    Windows CE内存泄漏
    MPEG4解码函数
    centos 7 gitlab安装 李刚
    docker 17.12.0ce 空间大小和容器大小限制修改 李刚
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9495050.html
Copyright © 2011-2022 走看看