自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(62)
  • 收藏
  • 关注

原创 并查集的简单实现

如果我们要将上面的图中的 3 和 7 合并,那么我们就需要先找到 3 的根和 7 的根,再将它们的根连接起来即可。我们只需要先判断当前节点是否为根,是就返回,不是就让它去判断它父亲是不是根,再没找到,就依次向上寻找即可。初始状态下,所有下标对应的值为 -1,表示每个元素自身为一个集合,集合内的个数为 1。例如:上图中的 5 和 7,它们找根时发现根相同,那就不需要合并,直接返回即可。我们还要考虑到,如果要合并的两个元素本身就在一个集合中,那么我们就不需要合并了。

2024-05-18 08:47:59 332 2

原创 信号知识详解

信号是linux系统提供的,让用户或进程给其他进程发送异步信息的一种方式。常见的信号处理方式:1、默认行为2、忽略3、自定义我们可以使用命令 kill -l 查看信号,也可以使用 kill -signum pid 对指定进程发送信号。例如:用 kill -9 将指定的死循环进程杀死。同样,我们也可以用 kill 命令发送其他信号。查看信号可以用 man 7 查看 man 手册。先介绍一个系统调用:signal(),它可以改变信号的默认行为,变为自定义。

2024-05-02 14:16:30 74 9

原创 文件描述符详解

在使用 open() 函数时,就是将磁盘中的文件加载到内存,创建一个 struct file 对象,然后将其属性内容等填好,然后链接到文件队列中,再返回新创建的 struct file 的地址,填到 fd_array[ ] 最小的,未被使用的下标中,再返回这个下标,就让我们拿到了文件描述符 fd。使用 read() 函数,就是先用 文件描述符 fd 找到对应的 struct file 文件对象,然后读取缓冲区的数据到 buf 中,如果缓冲区内没有数据,就将磁盘中的数据导入到缓冲区,再读。

2024-04-16 20:49:35 258

原创 共享内存详解

共享内存是操作系统在内存中开辟一块空间,通过页表与共享区建立映射关系,使两个进程看到同一份资源,实现进程间通信。

2024-04-12 20:08:43 713 1

原创 命名管道详解

管道都是基于文件的。1、当写端未关闭,读快写慢,当文件内没数据时,读端就会在read阻塞等待,写端写了再读2、当读端未关闭,写快读慢,写端就会一直写,直到写满,阻塞等读端读,然后再写。3、当写端关闭,读端就会读到0,表示读到结束。4、当读端关闭,如果写端还在写,会通过13信号杀死进程。5、在使用open时,先打开读端或写端中的任意一个,open()函数都会阻塞,只有读端和写端都打开了,才能正常运行。

2024-04-12 10:23:30 310

原创 进程间通信 (匿名管道)

进程间通信是一个进程把自己的数据交给另一个进程,它可以帮助我们进行数据传输、资源共享、通知事件和进程控制。进程间通信的本质是让不同的进程看到同一份资源。因此,我们要有:1、交换数据的空间。2、这个空间不能由通信双方任意一方提供。(要有一个独立的空间)

2024-04-10 23:05:24 763 5

原创 进程替换详解

e代表环境变量,程序替换不会替换环境变量,我们可以通过带e的接口设置新的环境变量。我们可以创建子进程,然后把子进程替换成我们需要的进程,执行其他程序的代码。并且我们代码中的 exec end 没有打出来,验证了进程替换后,后续代码不再执行。进程替换后:1、程序替换后,替换函数之后的代码不会被执行,因为进程已经被替换了。3、替换完成,不创建新的程序。我们可以观察得到,这些函数前面都有exec,后面跟着的。进程替换就是把当前进程替换成我们需要执行的进程,一般是通过系统调用实现。4、程序替换不会替换环境变量。

2024-04-08 20:45:15 232 4

原创 动静态库详解

静态库是程序在编译链接时将库的代码链接到可执行文件中,生成的可执行文件不需要库也可以运行。静态库是以 .a 为结尾的。打包静态库的方法:1、假设我们有一系列的 .c 和 .h 文件,第一步就是把 .c 文件编译成 .o 文件,通过指令:gcc -c 【.c文件名】,就会生成同名 .o 文件,如图:2、通过命令:ar -rc libXXX.a 【你要打包的 .o 文件名】,就可以生成静态库。

2024-03-22 20:00:17 754 3

原创 软硬链接详解

软链接就相当于Windows里的快捷方式,里面放的是目标文件的路径。用【 ln -s 目标文件名 软链接文件名 】可以 建立软链接。

2024-03-13 20:11:55 723 3

原创 进程等待详解

options 表示是否进行阻塞等待,0表示阻塞等待,1表示非阻塞等待,也可以用宏,WNOHANG表示非阻塞等待,WUNTRACED表示阻塞等待。在非阻塞状态下,成功返回子进程pid,还在等返回0,失败返回 -1.僵尸进程的危害十分严重,为了防止僵尸进程,及时地回收资源,我们可以采用进程等待的方式。3、waitpid()的作用也是等待,但它可以更细致的控制。是等待任意一个子进程,默认为阻塞等待(等待时父进程阻塞,不能做其他事)。2、父进程通过等待,获取子进程的退出信息。成功,返回等待的子进程的pid;

2024-03-13 16:58:31 496 3

原创 进程地址空间

当我们运行如上代码时,出现了地址相同而存的值不同的情况,由此我们可以验证,我们拿到的地址都是虚拟地址,fork之后创建了新的子进程,而新的子进程给它分配了新的一份虚拟地址,他们在各自的虚拟地址上对应到不同物理地址,修改 i 的值,就出现了上述情况。而这里指的内存并不是真实的物理内存,而是虚拟内存,每一个进程都有对应的虚拟内存,再通过页表与物理内存建立对应的映射,从而完成虚拟内存到物理内存的转换,这些工作都是由操作系统完成的,在每一个进程看来,它们都拥有完整的一块内存。b、将进程管理与内存管理进行解耦合。

2024-01-23 10:15:07 364

原创 vector的模拟实现

我们可以得知,_finish - _start就是顺序表vector的大小;_end_of_storage - _start 就是顺序表vector的容量。

2024-01-20 16:16:19 954 8

原创 系统调用创建子进程 --- fork基础认识

输入指令:man 2 fork 就可以看到fork的介绍( q 退出)fork()的参数为空,作用是:在调用fork()之后,创建一个子进程,子进程与父进程共享fork()之后的代码,数据各自私有一份,采用的是写时拷贝。返回值:父进程的返回值是子进程的pid,子进程的返回值是0。出错的话父进程返回-1,并且没有子进程被创建。运行结果第一行是父进程的,它的pid是31243,fork()的返回值是子进程的pid;第二行是子进程的,它的pid是41244,fork()的返回值是0。

2024-01-05 10:47:06 537 5

原创 进程的基础认识

进程是指 可执行程序 + 内核数据结构(内核为了管理进程而创建的数据结构)。

2024-01-03 20:31:10 409 4

原创 string类的模拟实现

我们先用strcmp可以实现字符串的 operator== 以及 operator> 再复用这两个函数完成接下来的函数的实现。因为在类里面第一个参数默认是this,而我们的习惯用法是cin >> string 、cout

2023-11-27 11:14:35 687 2

原创 泛型编程 -- 模板详解

在没有模板之前,如果我们写一个swap()两数交换函数,因为我们要支持 int 与int 交换 、double 与 double 交换等等情况,所以要实现swap()函数的多个重载,显得很繁琐,于是就引入了模板。模板就是在需要模板的地方的上面加一行:template 或 template需要多个参数还可以加:template这里 T 就代表的是一个不具体的类型,在调用时编译器自动识别会实例化或者我们手动给它实例化。

2023-11-17 10:31:20 123

原创 makefile的基础使用

1、建一个目录: mkdir Makefile/makefile(两个任意一个就可以)2、用vim打开3、在makefile里面的写法:目标文件 : 依赖文件==>小例子:[tab]依赖关系4、.PHONY:伪目标,让 make 命令 可以多次调用用法:以clean为例5、$@ 表示所有目标文件, $^ 表示所有依赖文件。

2023-11-10 11:35:34 67

原创 详解静态成员变量以及静态成员函数

类的静态成员变量是该类的所有对象共有的(只有一份),只能在类里声明,类外定义。相当于只属于类的全局变量。1、定义: 只能在全局中定义2、访问方式:(假如类A 中有公有静态变量 _a) ,可以用 A::_a 或 A a;a._a;访问3、不支持给缺省值(因为静态成员变量不走初始化列表)4、静态成员变量只能初始化一次,所以不能走初始化列表5、计算类的大小时不包括静态成员变量的大小,因为它在静态区,不算在类里。

2023-11-08 20:45:06 489 3

原创 文件权限详解

ll指令查看文件详细信息中,第一列就是文件类型。常见的文件类型有:1、 - :普通文件 (文本、源代码、图片、视频、可执行)2、 d :目录文件3、b :块设备4、c :字符设备5、l:链接文件6、p:管道文件7、s:socket文件。

2023-10-27 20:46:17 1964 5

原创 C++类的默认成员函数

在我们用C语言实现栈或队列等数据结构时,我们通常要写一个函数 Init() 来初始化它们,每次使用前都要调用一次,在我们使用的过程中容易忘记初始化导致程序错误,于是在C++中有了类的构造函数来帮助我们初始化编译器会在创建类对象时自动调用构造函数完成初始化,十分方便。那么构造函数应该怎么定义呢?1、构造函数的名字与类名相同2、构造函数没有返回值3、构造函数可以写多个构成重载(就像有时我们只要一个空栈,有时需要用数组初始化而成的栈)4、如果我们不写构造函数,

2023-10-25 21:16:21 170 1

原创 初识类和对象

1、在类里面定义的函数默认是 inline 内联函数2、声明与定义分离的函数只要在定义时在函数名前面加上 类名:: 就可以了。

2023-10-19 15:52:16 104 9

原创 C++入门之引用与内联函数

引用在语法上的理解就是起别名用法就是在类型后面加&,例子:int a = 1;int& b = a;上例所示,执行后,b就是a的别名,它们代表同一块空间,a的改变会影响b,b的改变也会影响a。

2023-10-17 15:08:25 837 11

原创 C++入门之缺省参数与函数重载

在写声明和定义分离的带缺省参数函数时,只有声明要给缺省参数。因为1、如果声明和定义都给的话万一给的不一样,冲突不好处理2、如果只在定义中给在头文件中就看不到了,不方便使用(C++支持,只包头文件就可以调用函数)只有声明中要写缺省参数若声明定义都给若只有定义给两者都会报错二、函数重载函数重载:C++中支持声明和定义同名函数(只要参数不同),这些同名函数就构成函数重载。这里的参数不同包括参数的类型不同,个数不同,顺序不同。

2023-10-13 20:19:49 253 4

原创 C++入门之命名空间详解

命名空间的功能就是区分不同的代码段,避免使用不同代码时带来变量名冲突的问题。在写C语言代码时,常常回面临命名冲突的问题。例如:可以成功运行。但是如果要使用 time.h 头文件时,就会与库发生冲突还有在包其他同学写的头文件时,也有会发生命名冲突的可能。为了解决这一问题,C++引入了命名空间,把自己写的代码放进命名空间中,就能解决这一问题。我们可以看到,上面显示重定义的错误在给我们自己定义的变量加上命名空间后就消失了程序运行后就打印出来了clock这个函数指针的值。

2023-10-11 18:47:04 202 3

原创 八大排序详解(默认升序)

直接插入排序的时间复杂度为O(n^2)空间复杂度为O(1)具有稳定性(相对位置不变),在接近升序的情况下效果最好,接近O(n)。

2023-10-07 19:35:02 411 6

原创 二叉树链式结构基础

所以在遍历过程中栈不会为空,栈为空就代表所有结点都遍历完成,结束循环。中序是先把左子树干掉,再把自己干掉,自己没了就找不到右孩子了,也不行。后序是先把左右子树干掉,在释放自己,刚好符合我们的要求,所以就用后续。层序遍历:和名字一样,就是一层一层遍历,如上图示例,层序遍历就是。前序遍历就是先保存根,然后向左探索,遇到空回来后向右探索。查找值为x的结点,遍历查找,前中后序都可以,找到返回即可。左右子树可以为空,就是单节点,根为空就表示探索完成,返回。先向左探索,等到为空返回时,再记录当前结点,最后向右探索。

2023-09-20 15:16:43 97 7

原创 堆排序与TopK问题

堆排序的思想就是先用数组模拟建大堆,然后把根结点与最后一个结点值交换,最后一个结点的值就是最大值,然后再把前(n-1)个元素重新建大堆,然后根结点与最后一个结点值交换,就找出了第二大的结点,....,重复操作就可以把数组排成有序。而建大堆可以找出最大的元素,再用最大的元素和最后一个元素换位,让最大的元素跑到最后面,再调用adjustdown(),调整建堆个数,让前n-1个数建堆,重复操作完成排序。:堆排序就是模拟建堆,然后找出最大的元素放最后一位,再找出次大的元素放倒数第二位,依次类推,最后变成有序。

2023-09-12 15:50:30 129 7

原创 栈和队列详解

队列:队列也是一种特殊线性表,只允许在一端进行插入,在另一端进行删除。栈:栈是一种特殊的线性表,它只能在一端进行插入和删除,插入和删除的一端叫做。检测栈是否为空,如果为空返回非零结果,如果不为空返回0。检测队列是否为空,如果为空返回非零结果,如果非空返回0。,因为它只能在一端进行插入和删除,所以它有着。,因为它是一端插入,另一端删除,所以它具有。获取队列中有效元素的个数。获取栈中有效元素个数。

2023-09-02 10:14:18 139 1

原创 牛客:数对

解题思路:看到题目的时候,一般第1反应是用两个循环暴力解题,时间复杂度是O(n^2),不能通过,所以要优化,通过找规律。式子:(n / y) * (y - k) +((n%y < k)?如果前式大于等于k,有n%y-(k-1)个可能。三、可以算出有 n/y 个完整的区间,所以有(n / y) * (y - k) 个可能。一、当 y <= k 时, 不可能符合题意,所以 y 从 k+1 开始遍历。二、当 x 属于区间 [0, y) 时,有 y-k 个可能的数对。

2023-08-24 23:06:31 107

原创 牛客:不用加减乘除做加法

大体思路:先不考虑进位用异或把数字“加”起来,在“加”上进位就可以了。题目所述不能用 + - * / 这四个运算符号,所以想到用位运算。

2023-08-22 20:51:28 39

原创 常用字符串详解(2)

strncpy函数和strcpy函数类似,但strncpy是拷贝num个字节,注意要保证destination字符串的空间够大。strncat函数的作用是在destination字符串的末尾添加从source字符串来的num个字符。当destination和source重叠时,strncpy函数就无法正常运行,要使用memmove函数。memcpy函数类似strncpy函数,但memcpy函数可以拷贝任意类型,不只是char类型。注意:destination字符串的空间要足够大.四、memmove函数。

2023-07-22 16:31:28 38

原创 自定义类型详解

int age;//年龄//名字//身份证号//要写分号int age;//年龄//名字//身份证号}p1;//声明的同时定义//定义p1 = { 18, "张三", "123456" };//初始化。

2023-07-21 18:49:01 50

原创 常用字符串函数介绍(1)

在C语言库函数中有些许多好用的字符串函数,下面我们一起来熟悉一下他们吧。(在使用时要包string.h头文件)

2023-07-13 14:45:09 38

原创 leetcode22(快乐数)

1、因为 n 的范围在1 到 2^31 - 1 之间,所以它的各位数的平方和不会超过810(10个9的平方和才810)因此。ps:这道题的走不是想链表一样的指向下一个,而是通过调用函数来更新快慢指针的值来走。2、快慢指针:定义一个慢指针走在后面,一个快指针走在前面,有循环的话一定会相遇,它不断运行求各位数的平方和这个运算810次之后它一定会出现重复的数。快乐数的相遇点一定是1,非快乐数的相遇点一定不是1,所以走完后判断相遇点是否为1就可以了。,所以就用快慢指针来解决这个问题。这道题是用了快慢指针来解决的。

2023-06-21 19:57:07 40 2

原创 码蹄集-购买数字

3、若在 2 的情况下,前一个字符为‘ 0 ’,那么就不能直接减一(因为不能为-1),所以就要把尾字符前连续的0都干掉(如果只解决一个0,那么有多个0的情况还是会错),就是用一个循环,,若第1个字符(首字符)为0,则把它删除。如果尾字符前一个字符为0,就将它改为9,遍历到非0位置停止,并将此位置的数字减一。4、在3的情况下可能会遇到(1000)的情况,所以干脆。将尾字符改为首字符,然后不断循环,这样就能构成回文了。,所以考虑若尾字符大于首字符,就无法直接赋值,要把尾字符前一个字符减一,再赋值。

2023-06-20 20:42:21 383 4

原创 leetcode第55题(跳跃游戏)

2、方程:dp[i] = max( dp[i-1] - 1, nums[i])4、结果:根据状态表示,如果dp[最终位置] >= 0 则可以到达,反之则不行。3、初始化,根据状态表示可知,初始化为dp[0] = nums[0]1、状态表示:dp[i] 表示到达 i 位置时还可以走多少步。第一次独立完成dp题,有不对的地方欢迎指正(~ ̄▽ ̄)~这个题目我是用动态规划来做的。下面就是我写的代码啦。

2023-06-08 20:01:20 72

原创 数据在内存中的存储

01111110 00000000000000000000000(中间的空格为了区分S,E,M),拿出来就将E减去127得到-1,0+1添小数点得到M:1.0,看出S:0为整数然后计算得到0.5。要反过来看,是十六进制:FF FF FF FB ,二进制就是上面所写的。b、反过来大端存储就是低地址存高位,高地址存低位。a、小端存储就是低地址存低位,高地址存高位。a、正整数的原码、反码和补码相同。2、那么原码、反码和补码的关系是什么呢?1、整型的二进制表示形式有三种:分别为。3、什么是小端存储和大端存储呢?

2023-06-02 16:29:09 50

原创 leetcode第746题(使用最小花费爬楼梯)

4、返回值: 根据定义,我们应该返回dp[costSize].(看方程发现,i = costSize时,cost数组会越界,且在第costSize个阶梯不用花钱,所以循环到costSize-1,出来再进行一次dp[i] = min(dp[i - 1] , dp[i - 2])就可以了)2、方程: dp[i] = min(dp[i - 1] , dp[i - 2]) + cost[i];1、先定义状态表示,我这里dp[i] 表示走到第 i 个位置花费了多少钱(包括第 i 个位置的花费)

2023-05-25 21:51:08 86

原创 leetcode第70题(爬楼梯)

1、用递归做,很多人一开始的想法都是用递归来写,但正常的递归会超出时间限制(因为有很多重复的计算),所以可以。用一个数组来存已经计算好的值。

2023-05-23 20:01:32 66

原创 数组越界造成死循环问题

【代码】数组越界造成死循环问题。

2023-05-20 14:53:02 36

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除