哪个是适合编程竞赛的 C++ BigInteger 类?

2023-12-01

我只是想知道对于不允许外部库的编程竞赛,C++ 中最好的 BigInteger 类是哪个?

主要是我正在寻找一个可以在我的代码中使用的类(基于类似的理由,我当然会自己编写它)。

我认为重要的主要因素是(根据其重要性):

  1. 应支持任意长度的数字及其运算。

  2. 从代码角度来说,应该尽可能小。通常,可以提交的源代码的大小有大约 50KB 的限制,因此代码应该比这个小得多。

  3. 应该尽可能快。我在某处读到 bigInt 类需要O( log( n ) )时间,所以这应该具有类似的复杂性。我的意思是它应该尽可能快。


到目前为止,我只需要 codechef 的无符号整数大数字,但 codechef 只​​提供 2KB,所以我在任何地方都没有完整的实现,只有该问题所需的成员。我的代码还假设long long至少有两倍的位数unsigned,虽然这很安全。唯一真正的技巧是不同biguint类可能有不同的数据长度。这里总结了一些更有趣的功能。

#define BIG_LEN()  (data.size()>rhs.data.size()?data.size():rhs.data.size())
    //the length of data or rhs.data, whichever is bigger
#define SML_LEN()  (data.size()<rhs.data.size()?data.size():rhs.data.size())
    //the length of data or rhs.data, whichever is smaller
const unsigned char baselut[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
                                   0,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
                                  25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
                                  41,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
                                  25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40
                                  };
const unsigned char base64lut[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62, 0, 0, 0,63,
                                    52,53,54,55,56,57,58,59,60,61, 0, 0, 0, 0, 0, 0,
                                     0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
                                    15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0,
                                     0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
                                    41,42,43,44,45,46,47,48,49,50,51, 0, 0, 0, 0, 0
                                    };
    //lookup tables for creating from strings

void add(unsigned int amount, unsigned int index)
    adds amount at index with carry, simplifies other members
void sub(unsigned int amount, unsigned int index)
    subtracts amount at index with borrow, simplifies other members
biguint& operator+=(const biguint& rhs)
    resize data to BIG_LEN()
    int carry = 0
    for each element i in data up to SML_LEN()
        data[i] += rhs.data[i] + carry
        carry = ((data[i]<rhs[i]+carry || (carry && rhs[i]+carry==0)) ? 1u : 0u);
   if data.length > rhs.length
       add(carry, SML_LEN())
biguint& operator*=(const biguint& rhs) 
    biguint lhs = *this;
    resize data to data.length + rhs.length
    zero out data
    for each element j in lhs
        long long t = lhs[j]
        for each element i in rhs (and j+i<data.size)
            t*=rhs[i];
            add(t&UINT_MAX, k);
            if (k+1<data.size())
                add(t>>uint_bits, k+1);
//note this was public, so I could do both at the same time when needed
//operator /= and %= both just call this
//I have never needed to divide by a biguint yet.
biguint& div(unsigned int rhs, unsigned int & mod) 
    long long carry = 0
    for each element i from data length to zero
        carry = (carry << uint_bits) | data[i]
        data[i] = carry/rhs;
        carry %= rhs
    mod = carry
//I have never needed to shift by a biguint yet
biguint& operator<<=(unsigned int rhs) 
    resize to have enough room, always at least 1 bigger
    const unsigned int bigshift = rhs/uint_bits;
    const unsigned int lilshift = rhs%uint_bits;
    const unsigned int carry_shift = (uint_bits-lilshift)%32;
    for each element i from bigshift to zero
         t = data[i-bigshift] << lilshift;
         t |= data[i-bigshift-1] >> carry_shift;
         data[i] = t;
    if bigshift < data.size
        data[bigshift] = data[0] << lilshift
    zero each element i from 0 to bigshift
std::ofstream& operator<<(std::ofstream& out, biguint num)
    unsigned int mod
    vector reverse
    do 
        num.div(10,mod);
        push back mod onto reverse
    while num greater than 0
    print out elements of reverse in reverse
std::ifstream& operator>>(std::ifstream& in, biguint num)
    char next
    do
        in.get(next) 
    while next is whitespace
    num = 0
    do 
        num = num * 10 + next
    while in.get(next) and next is digit
//these are handy for initializing to known values.
//I also have constructors that simply call these
biguint& assign(const char* rhs, unsigned int base)
    for each char c in rhs
        data *= base
        add(baselut[c], 0)
biguint& assign(const char* rhs, std::integral_constant<unsigned int, 64> base)
    for each char c in rhs
        data *= base
        add(base64lut[c], 0)
//despite being 3 times as much, code, the hex version is _way_ faster.
biguint& assign(const char* rhs, std::integral_constant<unsigned int, 16>) 
    if first two characters are "0x" skip them
    unsigned int len = strlen(rhs);
    grow(len/4+1);
    zero out data
    const unsigned int hex_per_int = uint_bits/4;
    if (len > hex_per_int*data.size()) { //calculate where first digit goes
        rhs += len-hex_per_int*data.size();
        len = hex_per_int*data.size();
    }
    for(unsigned int i=len; i --> 0; ) { //place each digit directly in it's place
        unsigned int t = (unsigned int)(baselut[*(rhs++)]) << (i%hex_per_int)*4u;
        data[i/hex_per_int] |= t;
    }

我还专门研究了乘法、除法、模数、移位等std::integral_constant<unsigned int, Value>,这使得massive改进了我的序列化和反序列化功能等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哪个是适合编程竞赛的 C++ BigInteger 类? 的相关文章

随机推荐

  • 使用 leiningen 时出现 ExceptionInInitializerError

    我是一个刚开始使用 Clojure 和 Leiningen 的初学者 在尝试使用各种 lein 命令时遇到了问题 虽然 lein deps工作正常 当我尝试使用时 lein plugin install
  • 当密码包含特殊字符时,“用户访问被拒绝”[重复]

    这个问题在这里已经有答案了 我几天来一直在搜索 SO 和网络 试图解决这个问题 SO 有很多类似的问题 但它们似乎都不是我目前正在处理的同一问题 我正在尝试使用 python 连接到远程 MySQL 数据库 以使用 pandas to sq
  • 为什么Python不使用^来表示数字的平方而是使用**来表示? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我见过的一些语言使用了 符号 并且它似乎没有为 Python 中的任何东西保留 这也让我感到困惑 因为 符号 非常 众所周知 Python 应该很容易使用 但使用 这有什么合乎逻辑的
  • java中的对象排序

    我想做嵌套排序 我有一个课程对象 其中有一组应用程序 应用程序具有时间和优先级等属性 现在我想首先根据优先级对它们进行排序 在优先级内我想按时间对它们进行排序 例如 给定此类 公共字段仅为了简洁起见 public class Job pub
  • 制作 X 与 Y 的图表

    我在 x 中有一些点 在 y 中有其他点 我正在尝试制作一个如图所示的图表 我希望创建的图表的点可以连接起来 在 c3 js 中 我不知道如何绘制 X 与 Y 的关系 我怎样才能实现像我的照片这样的效果 https jsfiddle net
  • pip 无法正确解决子/孙依赖关系

    我有一个模块的依赖关系树 其工作原理如下 表示依赖关系 a b c b ruamel yaml gt 0 16 5 c ruamel yaml lt 0 16 6 gt 0 12 4 我很清楚 ruamel yaml0 16 5将正确解决这
  • 如何轻松处理方向变化

    我正在开发一个以编程方式添加每个视图的 Android 应用程序 当用户转动屏幕时 我只想再次显示填写的值 有没有一种简单的方法让 Android 自动执行此操作 我的应用程序是完全动态的 因此它没有预定的布局 这使得它变得更加困难 那么
  • 为什么我们需要“nil”?

    我不明白为什么我们需要nil 1 何时cons项目序列 所谓的正确列表 在我看来 我们可以通过使用所谓的不正确列表来实现相同的目标 cons ed 对没有结尾nil 独自的 由于 Lisps 2 已经提供了一个原始过程来区分pair 和一个
  • 获取列表视图默认单击颜色,具体取决于设备

    在我的 Android 应用程序中 我使用列表视图和一些用户可以单击的线性布局 当然 我必须将 LinearLayout 的背景设置为 xml 文件 其中定义了所声明的按下 选择的内容 myView setBackgroundDrawabl
  • 如何通过 API 访问 Hadoop 计数器值?

    在 Hadoop 中 我们可以在 Map Reduce 任务中递增计数器 如下所示 context getCounter MyCountersEnum SomeCounter increment 1 您可以在日志中找到它们的值 作业完成后如
  • 流畅的 NHibernate 和计算属性

    我正在使用 Fluent NHibernate 并自动映射类 我在一个类中有一个计算属性 类似于 public virtual DateTime LastActionTimeStamp get return Actions Count 0
  • 获取oracle.jdbc.driver.LogicalConnection,需要oracle.jdbc.OracleConnection

    我正在尝试连接到在 WebSphere 上运行的 Java 应用程序内的 Oracle 数据库 我需要能够创建一个数组描述符以在调用过程中使用 代码如下所示 Connection conn null ArrayDescriptor arra
  • 如何整理 WinApi 函数的返回值?

    Simple 我怎么能够明确编组WinAPi 函数的结果 I know how to marshal parameters of WinApi functions in C but how can I also marshal the re
  • ListBox 项目可以跨多行吗? C# [重复]

    这个问题在这里已经有答案了 我想要一个 ListBox 控件包含跨多行的项目 本质上我想要的是每个项目跨越多行并且可以作为一个项目选择 有没有办法做到这一点 正如建议的LarsTech在他的评论中 所有其他评论都会导致某种完全编码的示例 这
  • 使用 NAND、NOR、NOT、AND 运算符进行多条查询

    我正在尝试设计一个学说查询 我对学说很陌生 但在我的另一篇文章的帮助下 我想出了一个在我的 Mysql 中运行时可以工作的查询 但我希望它能够转换 Doctrine 2 3 中的查询 有人可以帮助我吗 MySQL 查询 SELECT FRO
  • 将输入类型=文件替换为图像

    和很多人一样 我想定制丑陋的input type file 而且我知道如果没有一些技巧和 或javascript 但是 问题是 就我而言 上传文件按钮仅用于上传图像 jpeg jpg png gif 所以我想知道是否可以使用 clickab
  • 此错误消息在 appengine 中意味着什么?

    Search failed Traceback most recent call last File base data home apps s montaoproject 2013e 368508855356793432 search d
  • 在选定的输入字段下方显示一个 div?没有 JQuery

    如何在每次用户关注输入字段时显示 div 已经有一个 div 并且它被隐藏了 div的位置会根据所选字段的位置而改变 并显示在下面 这是我的代码 formFieldListWrapper style top formSelectedFiel
  • 创建掉落字母和单词的技术

    我正在寻找一种技术来创建一个窗口 其中的字母从上到下下降 随着它们的移动形成单词 这类似于苹果零售店中使用的滚动屏幕 我应该使用什么语言 他们的技术我可以借鉴吗 非常感谢 有一个很棒的资源是由法国程序员 Gerard Ferrandez 在
  • 哪个是适合编程竞赛的 C++ BigInteger 类?

    我只是想知道对于不允许外部库的编程竞赛 C 中最好的 BigInteger 类是哪个 主要是我正在寻找一个可以在我的代码中使用的类 基于类似的理由 我当然会自己编写它 我认为重要的主要因素是 根据其重要性 应支持任意长度的数字及其运算 从代