- 博客(69)
- 收藏
- 关注
原创 C++牛客题解:牛牛的快递(小数点的处理)
对于我们的题目来说,若是判断出了a为小数,则ret = 20 + ((int)a+1) - 1。1kg20元,2kg21元,所以最后结果为ret = 20 + kg数 - 1。我们可以定义一个tmp来存储a - (int)a,它的区间必定是[0-1)之间。因为我们将一个浮点数强行转为int类型的整数时,它必定会去除小数部分。不足1kg的部分按1kg算,所以我们需要把小数向上取整来处理。若是为整数,则ret = 20 + (int)a - 1。若tmp为0,则说明a是一个整数,否则说明a为一个小数。
2025-03-11 15:12:32
265
原创 Linux:文件系统(软硬链接)
文件 = 内容 + 属性而这个属性是存储在inode结构中的文件的数据都存储在“块”中,在Linux系统中还需要找一块地方来存储这个文件的信息(属性),这种存储文件信息的区域叫做inode,中文名为“索引节点”inode是保存文件属性的集合,一个文件只有一个inodels -l命令可以看到文件的详细属性,这些属性就是从inode中获取的inode内有一个唯一的标识符,叫做inode号,我们可以通过ls -i命令查看inode号。
2025-02-04 00:41:55
1128
原创 Linux:磁盘分区
一个文件可以是被打开的文件,也可以是未被打开的文件被打开的文件就是在内存中,未被打开的文件一般就是放在磁盘上的为什么要放在磁盘上呢?磁盘有什么优缺点?
2025-01-18 22:45:49
524
原创 Linux:基础IO
文件 = 文件内容 + 文件属性文件是存储在磁盘中的,磁盘是外设,磁盘上文件所有的操作本质都是对外设的输入和输出,简称IOLinux下一切皆文件所有的文件操作本质是文件内容操作和文件属性操作。
2024-12-27 22:29:13
1153
原创 C++:智能指针
当构造智能指针对象时来一份资源就要new一个引用计数,多个shared_ptr指向资源时就++引用计数即可,当shared_ptr析构时只需要--引用计数,当引用计数--到0后代表当前析构的shared_ptr是最后一个管理资源的对象,则析构资源。是C++11设计出来的智能指针,翻译是弱指针,他不同于上面的智能指针,他不支持RAII,也就意味着不能用他来直接管理资源,weak_ptr的产生本质是要解决share_ptr的一个循环引用导致内存泄漏的问题。n1和n2析构后,管理两个节点的引用计数减到1。
2024-12-21 17:59:34
816
原创 Linux:进程(环境变量、程序地址空间)
我们常见的计算机、服务器等大多数都遵守冯诺依曼体系输入设备:键盘、鼠标、摄像头、话筒、网卡、扫描仪等输出设备:显示器、磁盘、网卡、打印机等中央处理器(CPU):含有运算器和控制器等存储器:内存不考虑特殊情况;所有设备都只能和内存打交道正是因为有了冯诺依曼体系,让当代计算机成为了性价比的产物一般存储设备如CPU:存储量小,访问效率快,成本高如磁盘:存储量大,访问效率相对较慢,成本低所以有了内存这个中存储,中速度来调节二者,从而让计算机速度更快。
2024-12-14 21:37:13
882
原创 Linux:基础开发工具
CC=gccFLAGS=-oRM=rm -f.PHONY:clean:这些都是定义变量,这里定义了5个变量使用方法:$(变量名)这样也可以做到一样的效果,具体好处就和平时写代码的宏定义差不多。
2024-11-26 23:03:02
1141
原创 C++:异常
首先检查throw本身是否在try块内部,如果在则查找匹配的catch语句,catch语句若不匹配或throw不在try块内部,则退出当前函数,继续在外层调用函数链中查找匹配的catch语句,上述查找catch语句的过程被称为栈展开。如果到main函数,异常仍然没有被匹配就会终止程序,不是发生严重错误的情况下我们是不希望程序终止的,所以main函数中最后都会使用catch(...),它可以捕获任意类型的异常,但是不知道异常的错误是什么。程序的执行会从throw的位置跳到与之匹配的catch模块。
2024-11-23 17:18:30
651
原创 C++11(右值引用、可变参数、lambda、包装器)
在C++98中我们可以使用{}对一般的数组和结构体初始化C++11以后想统一初始化方式,试图实现一切对象皆可用{}初始化,它也叫做列表初始化内置类型支持,自定义类型也支持,自定义类型的本质是类型转换,中间会产生临时对象,优化以后可以变成直接构造{}初始化的过程中,可以省略掉=
2024-11-14 23:34:22
908
原创 C++:unordered_set、unordered_map类
unordered_set和unordered_map的底层是哈希桶实现的,使用方法和set/map都差不多所以它们的增删查平均效率是O(1)
2024-11-05 23:03:48
683
原创 C++:哈希表
从发生冲突的位置开始,依次左右按二次方跳跃式探测,直到寻找到下一个没有存储数据的位置为止,如果从右走到哈希表尾,则回绕到哈希表头的位置,如果往左走到哈希表头,则回绕到哈希表尾的位置。哈希表里只需要存储一个指针,当没有数据映射这个位置时,指针为空,当有多个数据映射这个位置时,我们把这些冲突的数据链接成一个链表,挂在哈希表当前位置的下面。这是扩容的逻辑,因为哈希表为了减少哈希冲突,哈希表的容量需要尽可能的是素数,所以这里写了一个函数列了一个素数表来拿到下一个接近2倍并且是素数的值。
2024-11-01 00:22:45
866
原创 C++:map和set类
string、vector、list、deque、array、forward_list,这些容器统称为序列式容器这些容器存储之间的值一般没有紧密的关联关系,比如交换一下,它依然是序列式容器map、set这些系列的就是关联式容器,两个位置有紧密的关联关系,交换一下它的结构就被破坏了map和set的底层是红黑树set是key搜索场景的结构map是key/value搜索场景的结构。
2024-10-25 23:45:20
354
原创 C++:红黑树
红黑树也是一颗搜索二叉树,它每个节点的颜色不是红色就是黑色,所以叫做红黑树它可以确保没有一条路径比其他路径长出2倍,因此它接近平衡。
2024-10-15 23:40:05
890
原创 C++:AVL树
AVL的本质就是一棵二叉搜索树,但是二叉搜索树若是高度不平衡,它的搜索速度就会大打折扣,AVL树就是优化的二叉搜索树,它能让整颗树的高度差不超过2,这样我们搜索起来的效率就是O(logN)新增节点后,影响到的是新增节点祖先节点的高度,所以我们更新平衡因子需要从parent节点开始持续往上更新调节,什么时候停止需要分情况讨论。当parent的平衡因子为-2,左子树的平衡因子为1,这时候单单的一次旋转是无法让这棵树平衡的。parent的平衡因子为-2,并且它的左节点的平衡因子为-1,则需要右单旋。
2024-10-07 23:11:24
1064
原创 Linux:常用指令
ls [选项][目录或文件] (可以不带选项和目录表示当前目录):对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。-a列出目录下的所有文件,包括以开头的隐含文件。-d将目录象文件一样显示,而不是显示其下的文件。如:ls –d指定目录-i输出文件的i节点的索引信息。如ls –ai指定文件-k以k字节的形式表示文件的大小。ls –alk指定文件-l列出文件的详细信息。-n用数字的UID,GID代替名称。(介绍UID。
2024-09-25 09:20:57
664
原创 C++:多态(协变,override,final,纯虚函数抽象类,原理)
如果派生类继承后不重写虚函数,那么该派生类也是抽象类纯虚函数某种程度上强制了派生类重写虚函数,因为不重写就无法实例化出对象。
2024-09-21 23:31:06
866
原创 C++:继承(protected、隐藏、不能被继承的类、)
继承是面向对象语言程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类的特性基础上进行扩展,增加成员函数或者成员变量,这样产生新的类称为子类。3. 子类的operator=必须要调用父类的operator=完成父类的复制,需要注意的是它们两个构成隐藏关系,子类调用时需要指定父类作用域。当父类的构造函数私有时,子类的构成必须要调用父类的构造函数,但是私有化后,子类看不见,所以就不能调用了,子类就无法实例化出对象。继承⼀定程度破坏了父类的封装,父类的改变,对子类有很大的影响。
2024-08-22 23:47:16
1258
原创 C++:模板 II(非类型模板参数,特化,分离编译)
这时候把p1和p2传进去比较的不是它指向的内容,而是比较的地址,所以这个比较是随机的也是错误的!顾名思义,它的类型形参并不是一个类型,就是用一个常量来作为类模板或函数模板的一个参数。这时候我们就可以让前面的Date*指针走我们特化的这个函数,结果就正确了。这个特化是特化为了指针,所以若是调用的指针类型就会调用到这个模板。4. 函数形参的类型必须要和特化的类型相同,如果不同编译器会报错。这个特化是特化为了引用,所以若是调用的引用类型就会调用到这个模板。3. 函数名后面跟一个,中指定需要特化的类型。
2024-08-21 22:32:16
837
原创 C++:priority_queue类
priority_queue类的本质是堆,下面是数据结构中的实现C数据结构:堆(实现、排序)-优快云博客它的实现也是和前面的栈和堆类似,一样用其他容器的成员函数来实现。
2024-08-20 23:42:31
445
原创 C++:queue类
queue类就是数据结构中的队列C数据结构:队列-优快云博客queue的性质还是FIFO先进先出queue类和stack类大的实现方式不一样,但是可以说是大差不差,都是复用其他容器来完成类C++:stack类(vector和list优缺点、deque)-优快云博客。
2024-08-18 21:37:40
464
原创 C++:stack类(vector和list优缺点、deque)
stack类就是数据结构中的栈C数据结构:栈-优快云博客stack类所拥有的函数相比与string、vector和list类都少很多,这是因为栈这个数据结构是FIFO先进先出的,它必须被有所限制,所以所能用的函数只需要那几个足矣栈可以用顺序表来实现,也可以用链表来实现,我们只需要控制它先进先出的特性即可,用什么容器实现取决于个人因为我们前面实现了vector和list类,所以再实现stack类就容易很多了,只需要复用vector和list容器内的函数即可。
2024-08-17 18:10:11
965
原创 C++:vector类(default关键字,迭代器失效)
vector其实就是数据结构中的顺序表,建议先学会顺序表C数据结构:顺序表-优快云博客public:private:这个iterator其实本质就和上一节string类的iterator一致,只不过这里是T*C++:string类(auto+范围for,typeid)-优快云博客有iterator就顺带把const_iterator定义了,方便稍后实现const迭代器的函数既然有了迭代器,那么begin和end也就很容易实现出来了。
2024-08-14 01:31:10
893
原创 C++:string类(auto+范围for,typeid)
string是一个字符串类string类和数据结构中的顺序表非常相似,只要我们懂了顺序表那么string类也是手拿把掐了C数据结构:顺序表-优快云博客为什么要有string类?和我们平时使用的 "内容"有什么区别?string类有非常多的接口,比如size,substr等等,这些都可以直接的帮助我们完成所需对字符串的改变在学习STL模板之前,我们还需要了解两个前置知识。
2024-08-08 00:31:19
965
原创 C++:内存管理(new,delete)
在C/C++中,都有一块虚拟地址,内部井然有序的将代码分成了几部分,如下表:栈:又叫堆栈,存放着非静态局部变量、函数参数、返回值等,栈是向下生长的内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信堆:用于程序运行时动态内存分配,栈是向上生长的数据段:存储全局数据和静态数据代码段:存储可执行代码、只读常量。
2024-07-22 18:13:48
967
1
原创 C++:类和对象 III(初始化列表、explicit、友元、匿名对象)
这两种写法给我们带来的效果都是一样的,但是无论怎么写我们的成员变量都要经过初始化列表一遍,就算没有写初始化列表也会!这里就是由于编译器的优化,由于A a2 = a1这个表达式做了两件事情,一件就是构造,另一件就是拷贝构造,所以编译器优化成了只有拷贝构造即可。这是因为类声明是先声明的_b,才声明的_a,所以初始化列表会先初始化_b,再初始化_a,而不是因为_a在初始化列表中初始化就初始化_a。那就是在初始化列表中!初始化列表中按照成员在类中声明的定义来初始化,于初始化列表中出现的先后顺序无关。
2024-07-18 23:24:15
1099
原创 C++:类和对象 II(默认成员函数,深浅拷贝)
浅拷贝是字节的拷贝,那么这个st1指针的字节也会被另一个对象st2所拷贝,这时候如果析构函数我们需要释放空间st1的空间,那么会根据_a的指向来free(_a),这时候st1的空间已经被销毁,总所周知,在C语言中如果我们写了一个日期类,如果我们想要在我们自己的类定义出的对象里面进行加减乘除法明显是不行的,你自己定义的类怎么能加减呢?如果别人需要使用我们的类,我们不想给他们使用,或者有别的意思,我们是可以恶搞一下的,取地址运算符重载,把地址变成一些莫名其妙的数字。
2024-07-15 15:00:47
906
原创 C++:类和对象 I(访问限定符、this指针)
class就是类,class是C++中的一个关键字当然类也可以是C语言中的struct,C++兼容struct,甚至还有一些升级定义类的方式class Date和C语言的struct一样,class是C++中定义类的一个关键字,Date是这个类的名字,我们需要在后面跟上一个 {}和;,{}里面可以放变量,函数等定义在类里面的成员函数默认为inline。
2024-07-12 17:56:34
1235
原创 C++:入门基础
因为编译器不能随意的展开一段代码,假设我们的func函数有1000条代码来完成,但是我们在main函数或者其他地方调用了func函数100次,全部都展开的话就是1000*100的代码量,这样会使我们的内存负担极大,相反,不展开的话只需要一个个call func函数的地址即可。上图的a是被const修饰的,只可读不可写,没有const限制的b自然也无法变成a的别名,因为b是可读可写,如果可以引用的话那a的权限就相当于被b放大了,这是不被允许的。
2024-07-10 20:57:25
1030
原创 C数据结构:排序
若按照错误方法来:例如:begin = 0,end = 3,那么mid = 1,begin1 = 0,end1 = 2,递归左右区间为[0,2]也就是begin = 0,end = 2,那么mid = 1,begin1 = 0,end1 = 2,这样又递归就会出现栈溢出的情况,所以必须要按照 上面代码的方式走。然后这个for循环做的就是遍历原数组,将原数组的值减去最小值,这个值映射到count数组中,让这个下标的值++,这样就会统计这个值出现的次数,而与原数组建立的关系就是减去一个min的关系。
2024-06-12 17:26:51
1136
1
原创 C数据结构:堆(实现、排序)
这时候就已经不是一个堆了,那么我们就需要用向下调整算法让第一个节点向下调整,使之重新成为一个堆,让最后的end--(也就是将我们刚刚找到的最大的数据或最小的数据排除在外),循环结束时我们的排序也就做完了。堆排的思想是先让堆顶最大(或最小的元素放到最后),然后把最后一个节点排除在外将其他节点看成一个堆,重新找出第二大(或第二小的元素放到倒数第二个位置),以此往复即可将数组顺序排好。在循环中,若第二个孩子节点的值小于第一个孩子的值,则child++,就能找到两个孩子节点中小的那一个。
2024-05-20 16:33:26
636
原创 C数据结构:队列
双向链表也很好,但是我们需要多定义一个prev指针,我们在出队和入队的过程中并不是很需要这个prev指针(如果只是为了出队方便完全可以定义一个队头节点的指针一直指向队头即可), 如果多了一个prev指针那么就意味着我们需要多维护一个指针变量,并且还会多消耗一点空间。队列这种特殊的结构既可以通过数组的方式实现,也可以链表的方式来实现,这时候就要考虑它两的优缺点来决定使用谁来实现了。这个QNode是必须要定义的,这是链表的基础,为了完成我们的队列而创建的,这是我们底层的结构。
2024-05-12 01:07:25
883
原创 C数据结构:栈
栈是一种特殊结构的线性表先来看看栈的图之所以说它特殊,是因为它的插入删除功能比较特殊栈的插入也叫作栈的插入只能在栈顶插入栈的删除也叫作栈的删除只能在栈顶删除。
2024-05-08 20:57:47
1073
原创 时间复杂度和空间复杂度
我们每个人都有每个人自己的思想,写出来的代码自然就各有不同但是代码也是分好坏的,每做一道题,使用到的算法也是有好坏的,那么我们如何来衡量这个好坏呢?下面将从时间和空间两个角度分析。
2024-04-30 15:45:19
344
原创 C语言:贪吃蛇游戏(万字解读超详细)
贪吃蛇这个游戏应该我们小时候都玩过吧我相信能够点进这个博客的应该都很熟悉这个游戏了如果对这个游戏不熟悉的可以网上查查怎么玩,这样才能对这个游戏有个清晰的认知该篇博客需要拥有C语言基础(对指针熟悉、会链表的使用)下面我们需要先学习一些C语言之外的东西认真坚持看完,我相信你一定能完成这个接近500行的C语言贪吃蛇项目该类型内部封装了两个成员,一个x,一个y,代表坐标我们可以将我们的控制台理解为一个平面坐标图横向正方向是x轴正方向,竖向负方向是y轴正方向。
2024-04-20 16:54:01
5450
3
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人