- 博客(62)
- 资源 (1)
- 收藏
- 关注
原创 浅谈定位new
之前在C++内存管理初探一文中谈到 C++ 内存管理存在比 C 中malloc/free一族函数更好用的new与delete。常规new的使用方法相信已经介绍比较清楚明晰了,今天本文尝试讲解一下定位new的使用规则。定位new(placement-new)定位new表达式时在已分配的原始内存空间中调用构造函数初始化一个对象。换句话说就是,现在空间已经有了,不需要定位new像常规new一样去给申请空间,只需要定位new在已有的空间上调用构造函数构造对象而已。定位new的使用格式:1.new (plac
2021-11-03 17:07:56
2438
原创 K个一组反转链表
K个一组反转链表给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。题目解析1.k个一组分别翻转,这就要我们要能对链表进行分组,每组是k个节点,各组单独翻转,意味着每组的翻转是组内行为,不可影响到别组,我在此处使用键值对pair将每组翻转前的头结点及尾结点存储起来2.需要注意的是若节点总数不是k的倍数,多出的节点不翻转,那么需要设一个标志,标明存不存在不需要翻转的组
2021-10-25 11:30:54
1764
原创 体验面试~
1.什么是多态?答:我理解的多态就是一种现象,这种现象表现出来是不同对象调用同一方法展现出不同的结果。而这种现象是由基类中虚函数在子类中被重写,且子类对象的指针/引用被强转为基类对象的指针/对象,再调用父类的方法引发的。呈现出的结果就是基类指针/引用调用基类方法,表现出子类方法的结果。这其中虚表指针的参与对多态起到了关键作用,子类对基类虚函数的重写使得父类虚表指针指向的对应虚函数被子类的函数覆盖,类型转化后的父类指针/引用调用父类的虚方法,实际上是调用子类的方法。这就是我理解的多态。问:虚函数?虚函数.
2021-08-22 17:16:24
362
原创 散列hash
散列hash散列哈希冲突hash函数的构造方法1.除留余数法2. 数字分析法3.平方取中法处理冲突的方法1.开放地址法a.线性探测再散列b.二次探测再散列c.随机探测再散列线性探测散列表模拟2.链地址法链地址法散列表模拟结语散列散列方法是一种计算式查找方法,又叫做hash(哈希)法或关键字地址计算。其基本思想是:首先在记录的关键字key和记录的存储位置p之间建立一个对应关系H,使得p=H(key),H称为hash函数,p称为散列地址。当创建hash表时,把关键字为key的记录直接存入地址为H(key
2021-07-08 14:48:39
1075
原创 map与set
map与set引言mapmap的主要常用方法模拟实现setset的主要常用方法模拟实现map与set的类似容器对比模拟实现引言这篇文章里介绍的东西都是STL的容器,包括map/set/unordered_map/unordered_set/multimap/multiset.上述容器中map与set的底层结构是带有迭代器的红黑树,其他容器的底层结构都是采用 链地址法实现的哈希表。mapmap的功能是将键值对形式的数据存储起来,建立一对一的映射关系,其底层结构为红黑树,这意味着数据是有序的。键值对
2021-07-08 10:12:28
104
原创 布隆过滤器
布隆过滤器布隆过滤器是布隆于1970年提出的一种紧凑型、比较巧妙的概率型数据结构,其特点是高效的地插入与查询,可用来表示某样东西一定不存在或者可能存在。布隆过滤器是通过使用多个哈希函数,将同一个数据映射到位图结构中,这种方式不仅可以提高查询效率,也可以节省大量的内存空间。布隆过滤器能干什么?小伙伴们有没有注意过像腾讯视频、抖音、bilibili等app在你手机通知栏里对你的推送?推送一条后,你点进去看了或者清除掉后,等会它又推送一条,这一条一定和之前的推送不一样,甚至从被安装到被卸载都没有推
2021-07-07 20:06:34
448
原创 简述位图C/C++
位图位图的概念位图的简单使用示意位图的应用位图的实现位图的概念所谓位图,就是使用比特位表示数据存在与否的一种数据结构,1个比特位表示一个数据的状态(存在/不存在)。而一个字节有8个比特这就意味着一个字节就可以表示8个数据的状态,这将大大节省保存数据的空间。例如,我要保存1-16这16的数字,通常的做法是申请16个整型空间,将其存储起来,这需要16*4=64个字节的空间。而如果使用位图,则只需要2的字节即可:2个字节有16个比特,每个比特有两种状态(0/1),则16个比特就可以表示这16个整型数字。但
2021-07-07 17:42:59
455
原创 AVL树的删除
引言AVL树的定义及性质及其重要的插入方法,我已在AVL树的插入一文中详细阐述过了,其中重要的旋转也已进行详细描述。本文就不再赘述了,直接使用,要是不清楚的小伙伴,还请移步AVL树的插入再回头复习一下下。AVL树的删除AVL树的删除步骤如下:寻找删除目标(存不存在,定位出目标)判断删除目标的类型,使用转换的思路,将其转化为删除叶子将删除目标与AVL树链接断开,调整平衡,完成删除寻找删除目标寻找删除目标的思路很简单,因AVL树也属于BST,因此寻找目标的做法与BST的删除思路基本一致。
2021-07-05 21:11:29
5188
8
原创 VS2019安装vld内存泄漏检测工具
vld下载在windows平台下,一个检测内存泄漏的工具是vld下载地址github地址加入库文件下载完成后,先找出VS2019库文件的位置:找到库文件存储路径随便打开一份代码,点击头文件,随便选中一个,右键点击转到文档如下所示,进行下一步操作:我们就找到库文件的存储路径了!加入vld.lib与vld.h打开Visio Leak Detector文件夹,会有一个include与lib文件夹先进include文件夹,将vld.h拷贝一份,将其粘贴到刚才找到的VS2019库文件存
2021-06-20 22:34:29
2619
5
原创 网络编程知识点
网络编程知识点IP地址端口协议:协议分层网络字节序标题数据的封装与分用套接字编程UDP与TCP的区别UDP协议通信程序的编写流程服务端客户端TCP协议通信程序的编写流程服务端客户端IP地址网络中,每一台主机的唯一表示标识名称数据类型常用技术ipv4uint32_tDHCP动态地址分配、NAT网络地址转换(通常用于组建私网)ipv6uint8_t ip[16]在网络中传输的每条数据中都会包含两个信息:源端IP,对端IP端口在一台主机上标识一个网络通信进程&l
2021-06-03 16:19:13
244
原创 带你一探红黑树的究竟
前言前不久写了二叉搜索树BST与高度平衡的AVL树的插入与删除无论是BST还是AVL树,树的中序遍历结果都是有序的,这是二叉搜索树的根本性质。不过AVL树比BST性能更上一层,因为AVL树在保持BST性质的同时,也保证树的高度是平衡的(左右子树高度喜相差不大于1)。有了BST与AVL树的基础,我们今天来搞红黑树RBTree!那么红黑树是什么?红黑树红黑树也是二叉搜索树,不同于AVL,红黑树在树的每个节点上增加了一个颜色标志,用于表示节点的颜色(RED or BLACK)。红黑树通过对任何一条从根到
2021-05-31 22:19:46
507
4
原创 AVL树的插入
什么是AVL树?AVL树又称为高度平衡的二叉搜索树。一棵AVL树如果不是空树,则符合以下性质:1.左子树与右子树的高度之差的绝对值不超过12.左右子树均是AVL树易知,二叉搜索树可以将查询效率提高至O(logh),h为二叉搜索树的高度。但当数据的插入是严格有序时,二叉搜索的效率会恶化至O(n),即线性复杂度。如下,有一组数据:不可否认,这还真是一棵二叉搜索树,但这棵树好嘛?不好!为什么不好?当我们想要查找数据时,查询路径和遍历查数组有什么区别?没有区别!都是线性复杂度。所以,两个俄罗斯数学家
2021-05-22 15:27:23
4401
原创 删除BST的节点
BST是什么?二叉搜索树BST(Binary Search Tree),又称为二叉排序树。该树要么是一个空树,要么具有以下性质:序号BST的性质1左树不空,则左树中所有节点中的值都小于根节点的值2右树不空,则右树中所有节点中的值都大于根节点的值3左右子树也是BST下图中的树便是一棵BST:BST的节点插入创建二叉搜索树比较简单,首先我们定义出二叉搜索树的节点类模板BSTNode,该类应具有三个成员,分别是左孩子指针leftchild,右孩子指针righ
2021-05-18 15:12:39
1785
3
原创 蛇形/回形矩阵(超详细!看了不会你来打我)
回型矩阵题目描述给你一个整数n,按要求输出n∗n的回型矩阵例如输入n=4,输出如下:分析回形矩阵的填充轨迹如下所示:填充顺序:最上面的行——>最右边的列——>最下面的行——>最左边的列——>最上面的行——>……首先,我们可以看出,填充轨迹存在大小不等的回形,我称之为外回与内回。如何控制外回结束后,会进入内回?需要4个变量作为边界限制条件,随着外回的进行,不断缩紧边界限制条件,逐步迫使轨迹进入内回。具体设置如下所示:设置了这4个限制条件还不够哦!因为这4
2021-05-15 13:40:03
23043
13
原创 C++继承
继承是什么?继承机制是面向对象程序设计实现代码复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。采用继承手段生成的类称为派生类继承呈现了面对想对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承使=是类设计层次的复用。为什么需要继承?假设现在不存在继承机制,现在我们实现了一个person类,这个类中含有人的一切属性及行为。我们现在想就人生阶段来实现对person的详细划分,处于不同人生阶段的人有不同的事情需要做,在实现时,即不同阶段的人有不同的方法及一些属性。如
2021-05-09 21:48:05
228
原创 机器人OJ
引言偶然发现LeetCode有七八道关于模拟机器人的OJ试题,心血来潮试做一下,大部分都是利用数学思维解决问题,还挺有意思。速算机器人分析这道题应该没什么问题,基础的字符串识别从左至右检测字符串检测到A执行x = 2*x + y;检测到B执行y = 2*y + x;codeint calculate(char* s){ int x = 1,y = 0; while(*s){ if(*s == 'A') x = 2*x + y;
2021-05-03 22:48:50
280
1
原创 关于【岛屿】-深度搜索
DFS深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止,属于盲目搜索。基本框架void DFS(形参列表){ if(判断边界){ 相应操作; } 尝试每一种可能{ 满足深搜条件 标记 继续向深度方向前
2021-05-03 13:31:47
364
原创 青蛙跳台你真的会码?
引言青蛙跳台阶问题是动态规划里较简单的题型了,因为状态转移方程很好找到。但上周末遇到一道青蛙跳台阶面试题,给我难住了。状态方程竟然一时半会想不到!虽然目前是推出状态转移方程了,但颇有感触,遂想就青蛙跳台阶这一类做个总结。普通青蛙跳台阶一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法?分析如上图,我们假设青蛙站在第i级台阶上那么,在青蛙一次只能跳1级/2级台阶上,它肯定是从第i-1级上跳1级上来的,或者从第i-2级台阶上跳2级上来的,不存在其他可能
2021-04-28 18:55:23
307
2
原创 进程信号
什么是进程信号?进程信号是一种事件通知机制,属于软件中断信号的作用:发生某事件时,打断进程当前操作,转而去处理这个事件通俗点的栗子:假设你正在学习,没有突发事件你不会停止学习。(此时你就是一个进程)此时你的母上大人做好了午饭,跑来叫你吃饭(吃饭信号)。然后你就去吃饭了,不学习了,吃完饭又回来学习(处理完信号回来继续作业)请注意!信号与信号量完全不是同一个概念!信号量是进程间通信(IPC)的方式之一,而信号是一种时间通知机制信号的种类在linux中使用kill -l可以查看所有信号,如下
2021-04-22 22:03:18
291
原创 管道及共享内存——IPC
进程间通信(IPC)进程间通信:操作系统为用户提供的用于实现进程之间进行通信的方式进程之间是无法直接通信的:因为每个进程都有独立的虚拟地址空间,访问的都是自己的虚拟地址,因此进程具有独立性,无法直接通信。进程间通信方式种类:管道共享内存消息队列信号量管道本质:在内核中开辟的一块缓冲区(内核空间中的一块内存)原理:多个进程通过访问同一块内核中的缓冲区实现通信特性通信方式半双工通信读取特性若管道中没有数据,则read会阻塞;若管道中
2021-04-20 10:29:48
231
原创 模拟stack/queue/priority_queue
stack要点1.stack遵从先进后出的规则,即先进栈的元素后出栈,入栈/出栈只能在栈的一端进行2.stack是作为容器适配器被实现的,容器适配器是对特定类进行封装,作为其底层的容器3.stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器应支持如下操作:·empty()——判空·back()——获取尾部元素·push_back()——尾部插入·pop_back()——尾部删除4.标准容器vector、deque、list均符合第3条要求,默认情况下,使用dequ
2021-04-20 09:46:04
96
原创 美团笔试
热搜小美被上司委派开发一个实时热搜的榜单。该榜单需要支持以下几种操作:操作1:接收到某条新闻的热度提升了多少,更新数据库,并调整榜单排行。初始时,数据库中不存在任何新闻。操作2:接收到用户的查询操作,返回热度最高的十条新闻。若此时数据库中新闻不足十条,那么有几条输出几条即可。例如数据库中新闻不足十条,那么只需要返回热度最高的三条新闻。当两条新闻热度相同时,新闻编号小的在前。特点地,当数据库中没有任何新闻时,需要给出null。现在你需要协助小美完成开发工作输入描述:第一行一个正整数n,表示接下来有
2021-04-19 13:21:24
375
原创 N皇后问题
N皇后是一道应用回溯算法的经典例题。N皇后研究的是如何将 N 个皇后放置在 N×N 的棋盘上,并且使皇后彼此之间不能相互攻击而两个皇后可以相互攻击的条件是:二者必须位于棋盘的同一行,或者同一列,或者同一斜线上N皇后比如现在研究4皇后问题,棋盘如下:我们要把4个皇后放入棋盘,使它们不能两两攻击!根据皇后互相攻击要满足的条件,我们很容易获得阻止皇后互相攻击的手段(怎么能容忍可爱的猫猫打架呢?):使任何两个皇后都不处于同一条横行、纵行或斜线上即可现在假设棋盘上已经放了3个皇后,要放最后一个
2021-04-10 22:12:02
696
7
原创 迭代器失效(list/vector)
什么是迭代器迭代器是一种面向对象的广义指针,用于指向容器中或流中的对象。可以看做是一种指向数据的指针。何谓迭代器失效迭代器失效是一种现象,由特定操作引发,这些特定操作对容器进行操作,使得迭代器不指向容器内的任何元素,或者使得迭代器指向的容器元素发生了改变。【No`te】后一种取决于编译器,部分编译器会将此种情况也视为迭代器失效,部分编译器并不视为失效)可能引起迭代器失效的操作因为不同的容器,迭代器不尽相同。可以引起list迭代器失效的相同操作不一定会导致vector的迭代器失效可能
2021-04-06 18:05:54
2725
5
原创 minishell的实现
何谓shell?实现要求可以运行运行效果Code#include <stdio.h>#include <sys/wait.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <pwd.h>#include <unistd.h>#define QUIT "quit"#define DEFAULT_PATH "path
2021-04-01 14:37:08
448
2
原创 进程控制~
进程创建pid_t fork(void)通过fork()创建一个子进程,返回值有两个:情况\返回值\进程父进程子进程创建成功子进程的pid0创建失败-1【Note】进程创建应用了写时拷贝技术pid_t vfork(void)通过vfork()创建子进程,会阻塞父进程阻塞:为了完成一个功能,发起调用,若当前不具备完成条件,则一直等待非阻塞:为了完成一个功能,发起调用,若当前不具备完成条件,则报错返回【Note】父子进程共用同一虚拟地址空间进程退出
2021-03-31 16:53:27
249
2
原创 模板初识~
模板是实现泛型编程的基础,泛型编程即指编写与类型无关的逻辑代码,是实现复用的一种手段。模板可分为:函数模板,类模板函数模板概念函数模板代表了一个函数族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。函数模板格式template<typename T1,typename T2,……,typename Tn>返回值类型 函数名(形参列表){函数体}如:template<typename T>void Swap(T& left,T
2021-03-31 10:27:21
1107
6
原创 深浅拷贝~
深浅拷贝初识先吃一个栗子:#include <iostream>#include <string.h>#pragma warning(disable:4996)using namespace std;char* ShallowCopy(char* src) { char* dst = src; return dst;}char* DeepCopy(char* src) { char* dst = new char[strlen(src) + 1]; str
2021-03-28 18:54:32
193
原创 fork()进程创建的一道例题
fork函数原型:pid_t fork();返回值:若成功调用一次则返回两个值:向子进程返回0,向父进程返回子进程ID(大于0);否则,出错返回-1函数说明:一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。子进程持有的是上述存储空间的“副本”,这意味着父子进程
2021-03-26 16:51:17
556
1
原创 二叉树层序遍历大法好!
层序遍历顾名思义,层序遍历就是把二叉树按层遍历,一层一层从根节点往深度方向遍历,每到新的一层,就把该层的所有节点遍历一遍,再进入下一层。举个栗子⑧:我们将下图中的二叉树划分为3层,并给每个节点按层从上到下,每层从左到右编上号码。现在我们要求得该二叉树的层序遍历序列,步骤如下:1.进入第0层,只有一个节点,将节点值添加入数组【1】;由于本层再无节点,进入下一层。2.在第1层,有两个节点,从左至右将其节点值加入数组【1,2,3】,进入下一层3.在第3层,有3个节点,不再赘述,我们将得到【1,2,3
2021-03-24 14:43:20
639
1
原创 C++内存管理初探
C/C++中程序中内存区域简单划分及介绍内核空间:存放内核代码和数据的空间,提供给内核使用栈(堆栈):存储非静态局部变量/实例化后的形参/返回值等等数据的空间,栈向下增长(即从高地址处向低地址处生长)内存映射段:用于高效映射I/O映射,装载共享动态库的空间。用户可使用系统接口创建共享内存,做进程间通信堆:在程序运行时用于动态分配的空间,堆向上增长数据段:存储全局数据与静态(static)数据,程序结束时由系统释放代码段:可执行的代码/只读常量...
2021-03-22 22:24:14
1111
9
原创 虚拟存储器
实地址与虚地址在早期的单用户单任务的操作系统中,每台计算机仅有一个用户,每次运行一个程序,程序还不是很大,单个程序完全可以存放在实际内存中,此时虚拟存储并没有多大用处。随着社会的进步,科技的发展,人们需要计算机处理更庞大更复杂的问题,运行在计算机中的程序越来越大,也越来越多,原来的单用户单任务系统不够用了,出现了多用户多任务系统。此时,有一个问题出现了:在程序设计时,程序需要的存储器容量往往与计算机系统实际配备的主存储器的容量之间存在矛盾。如,某些程序很大的内存的才能运行,而计算机的物理内存较小,不能满
2021-03-19 22:02:58
3177
7
原创 孤儿进程与僵尸进程
前言首先,我们应知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程再去创建新的子进程(也不一定)。一旦子进程被创建完毕,子进程与父进程是两个独立的进程,二者的运行与结束是一个异步过程,也就是说父进程无法预知子进程什么时候结束,子进程也不知道父进程什么什么时候需要自己的状态。那么当子进程完成自己的工作后,父进程需要调用接口wait()/waitpid(),获取子进程的状态。孤儿进程概念孤儿进程是指父进程先于子进程结束,那么此父进程创建的子进程将成为孤儿进程,进而被init进程(
2021-03-18 10:20:16
2218
12
原创 实现日期类:日期+天数/日期-天数/根据日期算星期几
实现要求1.可以任意构造一个日期对象2.允许日期对象进行自加,自减(前&后)3.日期对象前进/倒退任意天数可以得到另一个日期4.两日期之间可以计算相差天数5.允许两日期之间进行大小比较(>,<,>=,<=,==,!=)6.可以得到任意输入某年某月的天数需要编写的公有函数1.默认构造函数2.拷贝构造函数3.析构函数4.赋值重载函数5.减法重载函数【2个】6.加法重载函数7.比较运算符重载函数【6个】8.++重载函数【2个】,–重载函数【2个】实现
2021-03-16 08:54:23
642
1
原创 构造函数初探-C++
定义每个类都分别定义了它的对象被初始化的方式,类通过一个或多个特殊的函数控制其对象的初始化过程,而这些函数称为构造函数(constructor)。构造函数的任务:初始化类对象的数据成员构造函数被调用的时机:无论何时只要类的对象被创建,构造函数就会被调用。特征1.构造函数的名字和类名相同2.无返回类型,无返回值3.不能被声明为const型:当我们在创建一个const对象时,直至构造函数完成初始化过程,对象才真正意义上获得其“常量”属性。因此,构造函数在const对象的构造过程中可以向其写值4.
2021-03-10 10:23:07
894
6
原创 Linux调试器gdb的使用
Linux调试器-gdb首先,我们需要知道程序的发布方式有两种:debug,release。两种发布方式存在一定差异,debug发布方式产生的程序成为debug版本,该版本携带有调试信息,方便程序员对其进行调试。而release版本则不会携带调试信息,且会被各种优化,使得程序在空间占用及运行速度上都得到提升。要想使用gdb调试器,那当然要在允许调试的debug版本上进行操作了,因此我们必须得到源代码的debug发布版本,而要得到该版本程序的方式如下:gcc test.c -o test -g //利
2021-03-06 11:18:00
178
原创 剑指offer41-I.剪绳子
题目描述给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。示例示例 1:输入: 2输出: 1解释: 2 = 1 + 1, 1 × 1 = 1示例 2:输入: 10输出: 36解释: 10 = 3 + 3 + 4, 3 × 3
2021-02-28 18:53:22
156
原创 LeetCode150.逆波兰表达式
题目描述根据 逆波兰表示法,求表达式的值。有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。说明:整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。示例示例
2021-02-28 17:37:11
444
原创 剑指offer48.最长不含重复字符串
题目描述请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。示例示例 1:输入: “abcabcbb”输出: 3解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。示例 2:输入: “bbbbb”输出: 1解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。示例 3:输入: “pwwkew”输出: 3来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/zui-chang-bu-h
2021-02-28 16:58:29
151
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人