首页 > 其他分享 >实现动态大数结构

实现动态大数结构

时间:2023-10-27 23:22:43浏览次数:36  
标签:BigNum 大数 sign other && threshold const 动态 结构

  大数结构是一种常见的数据结构,在C++当中,我们常用vector来动态实现。除此之外,我们也可以仿照vector的思路,自己实现内存的动态分配,当内存容量达到上限时,用C-api realloc进行内存的重新分配。

#define REQUIRE2(p, q) assert((p) || (q))
#define REQUIRE1(p) assert(p)
#define INITSIZE 24

  先定义了几个宏,前两个是对表达式的判断,INITSIZE是动态大数结构的初始阈值,当超过了这个阈值之后,便发生扩容。

public:
        BigNum(const BigNum& other) : sign(other.sign), p(other.p) {}
        BigNum() {
            p = static_cast<char *>(malloc(INITSIZE));
            REQUIRE1(p);
        }
        BigNum(BigNum&& other) : sign(other.sign), p(other.p) {}
        ~BigNum() {
            free(p);
        }

        BigNum& operator=(const BigNum& other) = default;
        bool operator==(const BigNum& other) const = default;

  构造析构......注意析构要释放内存,防止发生内存泄漏。

void init() {
            sign = getchar();
            REQUIRE2(sign == '+', sign == '-');
            
            char c;
            char *start = p;
            while ((c = getchar()) != ' ' && c != '\n' && c != '\t' && c != '\r') {
                REQUIRE1(isdigit(c));
                if (start - p >= threshold - 1) {
                    void *mem = realloc(p, threshold << 1);
                    REQUIRE1(mem);
                    p = static_cast<char *>(mem);
                    start = p + threshold - 1;
                    threshold <<= 1;
                }
                *start = c;
                ++start;
            }
            start = nullptr;
        }

  这是关键的一部分,通过getchar函数,使得从键盘上动态读取字符,并且维护一个指针start,这样就可以实时统计大数结构当中的容量。在这里,前面定义的宏就派上用场了,需要严格检查读入的字符是否为数字(第一个读入的字符必须是+或者-符号)。

friend std::ostream& operator<<(std::ostream& os, const BigNum& big) {
            os << big.sign << big.p;
            return os;
        }

  重载输出函数。

private:
        char sign;
        char *p;
        std::size_t threshold = INITSIZE;

  在内部,维护了三个成员,分别是数的符号,指向初始内存位置的指针与阈值(阈值每次发生扩容时会乘2)。

 

  完整代码如下

#define REQUIRE2(p, q) assert((p) || (q))
#define REQUIRE1(p) assert(p)
#define INITSIZE 24

class BigNum {
    public:
        BigNum(const BigNum& other) : sign(other.sign), p(other.p) {}
        BigNum() {
            p = static_cast<char *>(malloc(INITSIZE));
            REQUIRE1(p);
        }
        BigNum(BigNum&& other) : sign(other.sign), p(other.p) {}
        ~BigNum() {
            free(p);
        }

        BigNum& operator=(const BigNum& other) = default;
        bool operator==(const BigNum& other) const = default;

        void init() {
            sign = getchar();
            REQUIRE2(sign == '+', sign == '-');
            
            char c;
            char *start = p;
            while ((c = getchar()) != ' ' && c != '\n' && c != '\t' && c != '\r') {
                REQUIRE1(isdigit(c));
                if (start - p >= threshold - 1) {
                    void *mem = realloc(p, threshold << 1);
                    REQUIRE1(mem);
                    p = static_cast<char *>(mem);
                    start = p + threshold - 1;
                    threshold <<= 1;
                }
                *start = c;
                ++start;
            }
            start = nullptr;
        }

        friend std::ostream& operator<<(std::ostream& os, const BigNum& big) {
            os << big.sign << big.p;
            return os;
        }

    private:
        char sign;
        char *p;
        std::size_t threshold = INITSIZE;
};

 

标签:BigNum,大数,sign,other,&&,threshold,const,动态,结构
From: https://www.cnblogs.com/ChebyshevTST/p/17793346.html

相关文章

  • vue 使用filter 把无限极分类遍历为树形结构
    <scriptsetuplang="ts">interfacelistType{id:numberurl:string}constdata=[{id:1,url:'/_nuxt/assets/images/america.png'},{id:2,url:'/_nuxt/assets/image......
  • 数据结构-顺序表
    一、概念1.顺序存储顺序存储结构,是指用一段地址连续的存储单元依次存储线性表的数据元素2.存储方式在编程语言中,用一维数组来实现顺序存储结构,在C语言中,把第一个数据元素存储到下标为0的位置中,把第2个数据元素存储到下标为1的位置中,以此类推。3.长度和容量数组的长度指的是数组......
  • python基于动态数量个列表求笛卡尔积
    需求有N个list,分别是listA,listB,listC。。。等等,N的数量不确定,现在对这些list的所有可能组合的值求笛卡尔积,比如(listA,listB),(listA,listC),(listB,listC),(listA,listB,listC)。。。求这里每个组合的笛卡尔积。分析对实现以上需求,可分解为2个部分:1.求所有list的组合2.对所......
  • CF练习题16 (毒瘤数据结构)
    Lomsatgelral把树拍成一条链,询问子树等于询问区间。这样一看这道题就非常莫队。但是有要求个数最多的颜色的编号,我们可以用线段树动态维护颜色的最大值。这样,一个无脑莫队线段树的暴力就做出来了。intn,a[N];intdfn[N],nfd[N],cnt;intb[N],siz[N];vector<int>g[N];in......
  • 队列数据结构实现
    1#include<iostream>2#include<fstream>3usingnamespacestd;45//顾客信息6structInform7{8intArrival;9intTyped;10intHandleTime;11intRestTime;12};1314//链式存储15structComsumer16......
  • delphi 运行时动态设置控件(类)属性值
    运行时动态设置控件(类)属性值代码运行时根据控件名称设置Alignment属性值usesSystem.Rtti;procedureTForm1.Button1Click(Sender:TObject);varvComponent:TComponent;vRttiCtx:TRttiContext;vRType:TRttiType;vProp:TRttiProperty;v:TValue;begin......
  • 动态规划合集
    动态规划笔记目录八种常见动态规划题型序列dp树形dp背包dp区间dp期望dp状态压缩dp数位dp计数dp动态规划优化合集DP技巧与DP杂题数据结构优化dp矩阵快速幂优化dp决策单调性优化dp斜率优化dp......
  • [vue学习]vue目录结构分析
    node_modules 依赖src源码.bablercbable配置.gitignore git忽略文件index.htmlhtml入口文件【通常在这里加移动端的view-port】package.json 管理模块 相当于maven的pom.xmlwebpack.config.jswebpack的配置文件【打包vue的文件,为浏览器能解析的文件】  .vue组件组......
  • 【Java集合】了解集合的框架体系结构及常用实现类,从入门到精通!
    前言通过Java基础的学习,我们掌握了主要的Java语言基本的语法,同时了解学习了Java语言的核心-面向对象编程思想。从集合框架开始,也就是进入了java这些基础知识及面向对象思想进入实际应用编码的过程,通过jdk中集合这部分代码的阅读学习,就能发现这一点。本计划在这篇中把框架体系和......
  • wpf webview2动态修改下载文件的下载路径 文件下载路径选择
    通过webview2下载文件时候会将文件保存在用户的默认下载目录,如果想调整成通过弹窗选择下载路径的方式则需要将默认行为做出修改。本文通过CoreWebView2_DownloadStarting这个事件来调整下载路径,基本思路为通过弹窗让用户选择需要保存的路径,如果用户取消了此操作则通过这个事件......