- 博客(25)
- 收藏
- 关注
原创 Linux 共享内存
共享内存区是最快的IPC一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程来传递彼此的数据。
2024-09-03 18:28:33
967
1
原创 Linux 进程间通信
只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创。管道是半双工的,数据只能向一个方向流动;管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。一般而言,进程退出,管道释放,所以管道的生命周期随进程。调用阻塞,即进程暂停执行,一直等到有数据来到为止。例子:从键盘读取数据,写入管道,读取管道,写到屏幕。
2024-09-03 01:50:10
854
原创 #LeetCode# 128.最长连续序列 (哈希+前驱数判定)
但是,仅仅是这样我们的算法时间复杂度最坏情况下还是会达到 O(n 2)(即外层需要枚举 O(n) 个数,内层需要暴力匹配 O(n) 次),无法满足题目的要求。我们考虑枚举数组中的每个数 x,考虑以其为起点,不断尝试匹配 x+1,x+2,⋯ 是否存在,假设最长匹配到了 x+y,那么以 x 为起点的最长连续序列即为 x,x+1,x+2,⋯,x+y,其长度为 y+1,我们不断枚举并更新答案即可。经过哈希去重后,元素还是无序的,如果采用快排的情况,此题的时间复杂度就不符合。题目最大难点在于设计出时间复杂度为。
2024-08-27 09:16:37
485
原创 C++ C/C++内存管理
new的原理1. 调用operator new函数申请空间2. 在申请的空间上执行构造函数,完成对象的构造delete的原理1. 在空间上执行析构函数,完成对象中资源的清理工作2. 调用operator delete函数释放对象的空间new T[N]的原理1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间申请2. 在申请的空间上执行N次构造函数delete[]的原理。
2024-08-26 18:40:40
949
原创 #LeetCode# 36.有效的数独 (对bitmap的应用)
请你判断一个9 x 9的数独是否有效。只需要,验证已经填入的数字是否有效即可。1-91-91-93x3'.'board =trueboard =false除了第一行的第一个数字从改为以外,空格内其他数字均与 示例1 相同。但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。1-9'.'
2024-08-25 02:21:50
596
原创 C++ 内联函数 inline
一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、频繁调用、不是递归的函数 采用。编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用。关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。不建议声明和定义分离,分离会导致链接错误。被展开,就没有函数地址了,链接就会找不到。修饰的函数叫做内联函数,编译时。修饰,否则编译器会忽略。
2024-08-24 21:51:19
302
原创 #数据结构# 单链表的实现3(C语言)
6.尾删结点(SListPopBack):7.头删结点(SListPopFront):8.在pos位置之后插入数据x(SListInsertAfter):9.删除pos位置的数据(SListErase):10.销毁链表(SListDestroy):6.尾删结点(SListPopBack):思路:我们需要找到最后一个结点,并且删除并释放内存,而倒数第二个结点即成为了新的尾结点。因此,我们不仅要得到尾结点的地址,还要得到倒数第二个结点的地址。仅仅通过一次遍历,我们
2024-08-24 19:54:16
2015
原创 #LeetCode# 206.反转链表(经典题的经典思路)(C语言)
空链表执行反转,在逻辑上没有错误,但是直接放进代码运行,则Prev,Cur,Next结点没有存在意义,会报错。所以我们可以为每个结点重新赋值,使得“看起来”链表结点顺序与原来链表相反。该题目的要求就是:返回一个地址,作为链头结点,该链表为原先链表的反转。如果通过迭代实现反转链表,我们需要将链表结点中的next反转。链表中节点的数目范围是 [0, 5000],请你反转链表,并返回反转后的链表。我们可以构造三个结构体指针。1.当Next为NULL时,
2024-08-24 19:53:56
1095
原创 qsort函数、sort函数
先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的。首先说一下, qsortqsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有多个重复值的数组来说,基本快速排序的效率较低,且不稳定)。集成在C语言库函数里面的的qsort函数,使用 三 路划分的方法解决排序这个问题。所谓三路划分,是指把数组划分成小于划分值,等于划分值和大于划分值的三个部分。具体介绍。
2024-08-24 19:53:20
1175
原创 #数据结构# 单链表的实现2(C语言)
所以,假如继续跟打印链表的判断条件相同,则跳出循环之前,结点就已经被遍历完全,最后一个结点的next指针也无法被我们找到。因此,尾插循环条件应该为while (node->next!打印链表中的遍历循环条件是:while(node!=NULL),意思就是当node指向最后一个结点,打印的任务就完成了,再进入一次循环,node就指向NULL,循环跳出。但是尾插结点不同,尾插结点需要当前最后一个结点的地址,才能通过该地址找到存放下一个结点的next指针,并将尾插新结点地址存放进next中。
2024-08-24 19:52:51
860
原创 #数据结构# 单链表的实现1(C语言)
即为第二个结点的地址,第二个结点中的next为第三个结点的地址......直到第三个结点以后,如果没有新的结点,则这个结点的next指向空,即。在SListNode结构体中,存放一个SListNode的结构体指针,这个指针即为指向下一位结点的地址,命名为“next”。先找头结点,通过头结点找下一个结点,找到一个,就打印一个,直到最后一个结点为止。简单来说可以说为“一环扣一环”,每个结点的数据都有着联系下一个结点的方式。的结点可以称为头结点,该结点中的next为。最后,由于是新的结点,
2024-08-24 19:52:40
1069
原创 #数据结构# 栈与队列的实现1 (C语言)
允许插入(Push)的一端为队尾,允许删除(Pop)的一端为队头。假设队列是Q=(a1,a2,……,an),那么a1就是队头元素,而an是队尾元素。或者不进行整体迁移,而采用扩容及改变下标的方法实现队列的头删功能,有点繁杂,所以这里我采用。所以我们进行插入数据时,新插入的数据总是位于队列尾端;进行删除时,删除的数据总是位于队列开头的数据。队列是一种先进先出的(First In First Out)的线性表,简称FIFO。进行实现,但是如果使用顺序表实现队列的情况下,其次,初始化时,队列没有元素,所以。
2024-08-24 19:49:46
2143
原创 计算机基础 | 谈一谈计算机的信息单位(地址,内存,以及进制转换)
只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。这里可能有些小伙伴会想到,a不是等于1吗,十六进制储存应该是 00 00 00 01才对,为什么这里是反的?字节 byte:8个二进制位(bit)为一个字节(B),最常用的单位,字节也就是B。两个数组成的,一个即是一个比特(bit)位,确实是四个地址,而且是连续的,其实上文的。
2024-08-24 19:47:56
3141
1
原创 LRU Cache
LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。什么是 Cache?狭义的Cache指的是位于CPU和主存间的快速RAM, 通常它不像系统主存那样使用 DRAM技术,而使用昂贵但较快速的SRAM技术。广义上的Cache指的是位于速度相差较大的两种 硬件之间, 用于协调两者数据传输速度差异的结构。
2024-08-17 17:58:17
288
原创 Centos7更新gcc版本(阿里云部分工具包失效)
这两个文件存放 devtoolset 以及 它的依赖文件 的镜像源,估计是阿里云镜像源已经停止更新的问题,CentOS-SCLo-scl.repo里面默认的镜像源 还是Centos官方 的古早网址(现在网址已经不一样了)如果你想要让新安装的 GCC 版本成为默认版本,需要更改环境变量。6.设置默认的 GCC 版本:( .bashrc 或者 .bash_profile)可能是因为你没有以登录会话的方式启动终端(这在图形用户界面中是常见的)。这意味着,如果你是在图形用户界面下打开一个新的终端窗口或标签,
2024-07-23 08:19:37
2929
2
原创 terminate called after throwing an instance of ‘std::regex_error‘
较新版本的编译器通常会对正则表达式的性能进行优化,包括编译和匹配速度。使用较低版本的编译器可能会导致这些库无法编译或运行。本地用户的G++版本是centos 7 默认的4.8.5,而root用户,在此前更新G++版本至8.3.1。G++版本较低可能会影响正则表达式的编译和运行,特别是对于一些较新的正则表达式特性和优化。事情缘由:今天整理项目的时候,发现了此前能跑通的服务器,今天重新跑的时候,突然跑不通了。:较低版本的编译器可能不支持某些较新的正则表达式语法,导致编译错误或运行时行为不一致。
2024-06-28 17:51:27
435
原创 棋盘覆盖问题
在一个2^k×2^k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖;问:是否能用这些骨牌覆盖棋盘?问题解析目前有16*16的棋盘,特殊方块如图上所示。对于此时的左上角,相当于是一个全新的棋盘,其尺寸为大棋盘的1/4,新棋盘拥有特殊方块;其他三个也同理,将第一块骨牌拆分,分别当作各自棋盘的特殊方块。
2023-11-05 22:45:41
414
1
原创 C++ 继承、菱形继承问题、虚拟继承、虚基表
1. 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设 计出菱形继承。否则在复杂度及性能上都有问题。2. 多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。3. 继承和组合public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。优先使用对象组合,而不是类继承。
2023-10-08 10:59:21
163
1
原创 priority_queue的模拟实现
优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成 堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意: 1.默认情况下priority_queue是大堆。 2.(重要) 如果priority_queue中放自定义类型的数据,“用户需要在自定义类型中”提供> 或者< 的重载,以重新定义在此类中">"和"
2023-09-17 20:03:10
79
1
原创 模拟实现vector中reserve接口所遇到的拷贝问题
结果:报错,程序崩溃问题分析:1. memcpy是内存的二进制格式拷贝,将一段内存空间中内容原封不动的拷贝到另外一段内存空间中。2. 如果拷贝的是自定义类型的元素,memcpy既高效又不会出错,但如果拷贝的是自定义类型元素,并且自定义类型元素中时,就会出错,。
2023-08-24 22:23:13
137
1
原创 vector 迭代器失效问题
编译器优化可能会影响程序的执行方式,有时优化可能掩盖一些潜在的错误,尤其是在小型程序或测试环境中。不同的编译器和运行时环境处理未定义行为的方式不同,有时可能不立即暴露问题。迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装。,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。这里看出删除前后,it 指向元素的地址都是同一个,且迭代器 it 看起来没有失效。这种形式来更新迭代器,确保迭代器不会失效。
2023-08-21 22:45:15
94
1
原创 string的浅拷贝、深拷贝、写时拷贝
(调用析构时,首先析构s2,s2与s1指向同一块内存,所以s2析构完成后,s1的内存空间也被清除,等到s1析构时,同一块空间再次被释放,多次释放就会引起程序崩溃)深拷贝产生浅拷贝的主要是因为在进行拷贝构造或是赋值运算符重载时,直接将就对象的内容原封不动的粘贴给新对象,因而在空间释放时形成了多次释放问题,因此如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。传统string类的写法。
2023-08-18 16:53:01
89
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人