- 博客(91)
- 收藏
- 关注
原创 【剑指Offer 61】扑克牌中的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
2021-04-08 17:21:47 197
原创 【C++】单词识别
输入一个英文句子,把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来,要求能识别英文句号和逗号,即是说单词由空格、句号和逗号隔开。输入描述:输入有若干行,总计不超过1000个字符。输出描述:示例:输入:A blockhouse is a small castle that has four openings through which to shoot.输出:a:2blockhouse:1castle:1four:1has:1is:1opening
2021-01-15 20:29:27 1342
原创 C++_STL中的关联式容器
STL中的容器,比如:vector、list、deque、forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。1、树形结构的关联式容器 树形结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同特点是:使用平衡搜索树(即红
2021-01-08 19:59:36 459 1
原创 C++_继承
1、什么是继承? 继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。继承是类设计层次的复用。1.1、struct在C语言与C++中的区别? C语言中:struct是用户自定义数据类型,是一种数据结构的是实现体。 C++中:struct是抽象数据类型,支持成员函数的定义,是一种对象的实现体。1.2、C++中class和struc
2020-12-13 19:39:54 488 1
原创 C++_string
C语言中实际没有专门的字符串类型,如果要表示字符串:char* 或者字符数组(\0)。C语言还提供了一个专门用来进行字符串操作的库函数(<string.h>)。C++标准库提供string类类型,支持C里面的所有操作,另外还增加了其它更多的功能。string的常用接口1、常见构造:string(); //构造一个空字符串,以\0结尾string(size_t n, char ch); //用n个字符串ch构造一个string类型的对象string(char* str); //用
2020-12-08 15:20:51 181
原创 C++_STL
1、什么是STL STL(standard template library)是C++中的标准模板库,STL实际就是对常见数据结构((顺序表、链表)+栈和队列+二叉树+哈希)以模板的方式进行封装。 通俗来讲,其目的是替用户组织数据,里面还增加了一些非常灵活的通用算法。 通用:与数据类型无关;与数据结构无关(任意类型数据结构组织的数据都可以进行操作)2、STL六大组件容器 STL对常见数据结构的封装(模板类)。 序列式容器:string、vect
2020-12-07 21:49:54 118
原创 C++_模板
1、概念 与铸造东西所使用模具类似,用户写一个模具,当按照不同类型对模具进行实例化时,编译器就会根据所使用的类型以及模板来生成具体类型的代码。2、模板分类 函数模板和类模板3、函数模板 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。// 返回值类型 函数名(参数列表){}template<typename T>void Swap( T& left, T& right) { T t
2020-12-07 21:17:48 106
原创 C++_动态内存管理
1、内存分区C/C++程序运行起来,内存划分的区域,以及每个区域的作用:内核空间:放置操作系统相关的代码和数据。用户不能直接进行操作,可以通过调用系统提供的API函数;栈:与函数调用相关,非静态局部变量 / 函数参数 / 返回值 / 寄存器信息等等。内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库,用户可使用系统接口创建共享内存,做进程间通信;数据段:存储全局变量和静态数据代码段:可执行的代码 / 常量进行分区的原因---->方便数据的管理2、malloc/cal
2020-12-07 17:07:45 155
原创 C++_类和对象
1、面向对象和面向过程的区别1.1、面向对象和面向过程的区别 面向过程:是以函数驱动的,通过函数之间的相互调用次序来完成事情,重视完成该件事的步骤。 面向对象:关注的不再是完成事情的步骤,关心:如何通过对象之间的交互将事情完成。1.2、C++和C语言的区别:面向对象和面向过程;C++编译器对语法的检测更加严格;C++语言更加的人性化;C++支持面向对象:封装、继承、多态;C++独有的STL;C++更适合做比较复杂、大的工程。2、封装2.1、什么是封装:将数据和操作数据
2020-12-07 01:01:58 499
原创 C++_函数重载&引用&内联函数
1、缺省参数1.1、概念:在声明或定义函数时,给函数的参数设置一个默认值,当用户对函数进行调用时,如果传递了实参,则使用用户传递的实参;如果没有传递则使用默认值。1.2、分类:全缺省参数:所有参数都带有默认值;半缺省参数:部分参数带有默认值。规则:必须从右往左依次给出。1.3、特性:缺省参数必须从右往左给出;不能在函数声明和定义的位置同时给出;缺省参数在提供时—常量||全局变量;C语言不支持。2、函数重载2.1、概念:相同作用域下,函数名字相同,参数列表必须不同(参数个数、参数
2020-12-06 18:04:37 578
原创 C语言_位运算和常考操作符
1、操作符优先级指针最优,单目运算优于双目运算。如正负号;先算术运算,后移位运算,最后位运算。请特别注意:1 << 3 + 2 & 7等价于 (1 << (3 + 2))&7;逻辑运算最后结合。简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符2、移位操作逻辑移位:针对的是无符号类型的数据 左移:丢弃最高位,低位补0; 右移:丢弃最低位,高位补0。算术移位:针对的是
2020-12-06 18:03:49 104
原创 C语言_结构体
1、结构体是什么? 结构体是由一批数据组合而成的一种新的自定义类型。2、为什么需要有结构体的类型? 内置类型不能表示所有的场景,比如:学生群体;描述学生:name、age、gender、height。struct Student{ char name[20]; int age; char gender[3]; double height;};3、结构体内存对齐(1)为什么需要内存对齐? 1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件
2020-11-27 18:31:07 938
原创 C语言_指针
1、指针是什么? 指针首先是C语言中的一种数据类型,用该种类型定义的变量成为指针变量,该变量中存储的是一个地址。2、指针的大小? 32位系统下:4字节; 64位系统下:vs编译器是按照32位方式编译的:4字节;可以对编译器进行设置,让编译器按照64位方式编译:8字节。3、指针的操作 解引用 * 和 -> ->一般应用于类和结构体中,用于访问其成员。注意:对指针进行++、- - 、+、-数字,一般针对的是指针指向一段连续的空间才有意义。指针相加没有意义,指针相减指两个
2020-11-27 15:53:56 324
原创 【C++】倒置字符串
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I输入描述:每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100输出描述:依次输出倒置之后的字符串,以空格分割输入例子1:I like beijing.输出例子1:beijing. like I代码:#include <iostream>#include <string>#include <algo
2020-11-26 02:31:46 2202
原创 【C++】连续子数组的最大和
题目描述:输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4]输出: 6解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。解题思路:这个可以使用一个动态规划的思路,用 dp[i] 表示以 nums[i] 结尾的最大和,那么可以得出递推表达式 dp[i] = max(dp[i - 1] + nums[i], nums[i])因为如果以 nums[
2020-10-19 15:14:04 1285
原创 string类的模拟实现
C++ 的一个常见面试题是让你实现一个 String 类,限于时间,不可能要求具备 std::string 的功能,但至少要求能正确管理资源。简而言之就是实现string类的构造、析构、拷贝构造、赋值运算符重载class bit { class string { public: //构造函数(全缺省构造函数) string(const char* str = "") :_str(new char[strlen(str) + 1]) { strcpy(_str, str); }
2020-08-12 21:22:09 149
原创 线程安全的单例模式
单例模式:是非常典型常用的一种设计模式(大佬们针对典型场景设计的解决方案)单例模式的特点:某些类,只应该具有一个对象(实例),就称之为单例。例如一个男人只能有一个媳妇。在很多服务器开发场景中,经常需要让服务器加载很多的数据(上百G)到内存中,此时往往要用一个单例的类来管理这些数据。饿汉方式和懒汉方式吃完饭立刻洗碗,这就是饿汉方式。因为下一顿吃的时候可以立刻拿着碗就能吃饭;吃完饭,先把碗放下,然后下一顿饭用到这个碗了再洗碗,这就是懒汉方式饿汉方式的实现: 使用static就可以—将
2020-07-30 15:26:44 120
原创 线程池
在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在操作系统中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。优点:避免峰值压力下,资源耗尽的风险;节省线程创建 / 销毁带来的时间成本封装一个线程池: 一堆已经创建好的线程 + 线程安全的任务队列。为了让每一个线程针对不同的任务,有不同的处理方法,让线程灵活起来。向线程池抛入数据的时候,顺便将处理函数一起抛入,线程池中的线程使用函数处理数据即可,最好这个
2020-07-30 14:15:50 116
原创 基于信号量的生产者与消费者模型
信号量本质:计数器 + 等待队列 + 向外提供的使执行流阻塞 / 唤醒的功能接口对资源进行计数,统计当前的资源数量,通过自身的计数,就可以进行条件判断,是否能够进行操作,若不能获取资源,则阻塞当前执行流。在程序初始化阶段,根据实际资源数量初始化信号量计数器数值,在每次获取资源之前,先获取信号量(先去判断计数是否大于0,若大于0,则计数-1,直接返回,获取数据;否则阻塞当前执行流)其它执行流生产一个资源后,先判断计数器是否 <0 ,若小于0,则唤醒一个执行流,然后进行计数 +1接口介绍:se
2020-07-30 13:37:56 226
原创 生产者与消费者模型
应用场景:不断的生产数据并且进行处理的场景模型的特点:解耦合,生产者模块与消费者模块并不直接交互,都是仅操作线程安全的队列支持忙闲不均,队列中有多个节点可以起缓冲作用支持并发生产者与消费者模型的实现:一个场所,两种角色,三种关系生产者与生产者应该具备互斥关系消费者与消费者应该具备互斥关系生产者与消费者应该具备同步与互斥关系代码实现:#include <cstdio>#include <iostream>#include <queue>#in
2020-07-30 12:44:10 155
原创 如何实现线程安全?
线程安全:在多个执行流对同一个临界资源进行操作访问,不会造成数据二义那么如何实现线程安全?同步与互斥互斥通过保证同一时间只有一个执行流可以对临界资源进行访问(一个执行流访问期间,其它执行流不能访问),来保证数据访问的安全性。如何实现互斥:互斥锁互斥锁:本质上是一个 0/1计数器,0-不可访问 1-可以访问,计数器初值为1。每一个线程访问临界资源之前,先判断计数,当前临界资源的状态(是否有人正在访问,正在访问的线程将状态置为0)接口介绍:pthread_mutex_t //互斥锁变量类型
2020-07-30 00:46:59 413
原创 进程信号
信号是什么:信号就是一个软件中断,通知进程发生了某个事件,打段进程当前的操作,去处理这个事件。信号是多种多样的,并且一个信号对应一个事件,这样才能做到收到一个信号后,直到到底是一个什么事件,应该如何处理。(但是要保证必须识别到这个信号)信号种类:62种,1-31是非可靠信号;34-64是可靠信号。信号周期:产生,进程种的注册,进程种的注销,捕捉处理。信号的产生:硬件:ctrl + c , ctrl + | , ctrl + z软件:kill命令:kill -signum pidint k
2020-06-15 22:00:20 113
原创 进程间通信
进程间以为每一个进程都有一个虚拟地址空间,在保证了进程独立性的同时,却使得进程间无法直接通信,因此需要操作系统来提供进程间通信方式,并且因为通信场景不同,提供的方式也有多种。进程间通信的目的:数据传输:一个进程需要将它的数据发送给另一个进程资源共享:多个进程之间共享同样的资源通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时需通知父进程)进程控制:有些进程希望完全控制另一个进程的执行(如Debug)进程,此时控制进程希望能够拦截另一个进程的所有陷入和一场
2020-06-15 20:22:02 126
原创 网络基础——数据链路层
数据链路层:用于两个设备(同一种数据链路节点)之间进行传递以太网协议mac地址:是一个无符号6个字节的整数 uint8_t mac[6]源端mac / 目的端mac:标识从哪个设备传输到哪个设备——设备之间的识别类型:网络层协议类型——用于数据分用CRC:帧尾校验和ARP协议:地址解析协议,通过IP地址获取指定主机的mac地址——介于网络层与链路层之间的协议。发送端将arp请求...
2020-04-19 21:45:33 199
原创 网络基础——网络层
在复杂的网络环境中确定一个合适的路径协议头格式4位协议版本:IPV4 / IPV64位首部长度:记录IP报文长度,因为IP报头中也有40字节的选项数据,以4字节为单位8位TOS字段:3位优先权字段弃用;4位服务类型:最小延时,最大吞吐量,最高可靠性,最小成本;1位保留。16位头部长度:IP报文的长度(包含头部)—64k;IP报文中报头最小长度是20字节,因此IP报文中的数据不能超过6...
2020-04-19 17:08:49 466
原创 TCP协议详解
TCP全称为“传输控制协议(Transmission Control Protocol)”,人如其名,要对数据的传输进行一个详细的控制。TCP协议段格式16位源端口/16位目的端口:负责实现应用程序之间的数据传输32位序号/32位确认序号:用于实现tcp在传输层的包序管理——tcp有序交付数据4位头部长度:以4个字节为单位;4位保存的最大数字是15;因此tcp报头最大长度是1...
2020-04-16 17:17:17 446
原创 UDP协议
UDP协议端格式16位源端口与16位目的端口:负责应用程序之间的数据传输,标识数据从哪来到哪去16位校验和:校验数据一致性(发送的数据与接收的数据是否一致)——二进制反码求和发送数据的时候,将校验和设置为0,然后从报头第0个字节开始,每个字节进行取反相加,超出16位的部分(求和进位部分)取出来再次与低16位进行相加,最终得到的数据填充到校验和中;接收方同样对接收到的数据进行二进制反码求...
2020-04-16 13:12:35 180
原创 【C++】斐波那契凤尾
题目描述:NowCoder号称自己已经记住了1-100000之间所有的斐波那契数。为了考验他,我们随便出一个数n,让他说出第n个斐波那契数。当然,斐波那契数会很大。因此,如果第n个斐波那契数不到6位,则说出该数;否则只说出最后6位。输入描述:输入有多组数据。每组数据一行,包含一个整数n (1≤n≤100000)。输出描述:对应每一组输入,输出第n个斐波那契数的最后6位。示例:输入...
2020-03-31 14:46:13 291
原创 【C++】分解因数
题目描述:所谓因子分解,就是把给定的正整数a,分解成几个个素数的乘积,即a = a1×a2×a3×…×an,并且1 <a1≤a2≤a3≤…≤an 。其中a1,a2,…,一个可转换的素数。先转换一个整数a,请输出分解后的因子。输入描述:输入包含多组数据,每组数据包含一个正整数a(2≤a≤1000000)。输出描述:对应每组数据,以“ a = a1 * a2 * a3 ...”的形式...
2020-03-31 13:10:55 4071
原创 归并排序
算法介绍:归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。基本思想:基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。可以将A,B组各自再分成二组。依此类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了...
2020-03-24 15:23:35 74
原创 快速排序
算法介绍:快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法。分治法基本思想:先从数列中取出一个数作为基准数。分区过程将比这个数大的数全放到它的右边,小于或者等于它的数全放到左边。(升序)再对左右区间重复第二步,直到各区间只有一个数C++代码实现:#include <iostream>using namesp...
2020-03-24 13:57:41 75
原创 HTTP协议
虽然我们说,应用层协议是我们程序员自己定的。但实际上,已经有大佬们定义了一些现成,又非常好用的应用层协议,供我们直接参考使用,HTTP(超文本传输协议)就是其中之一。URL平时我们俗称的“网址”其实就是说的是 URL网址:统一资源定位符。在网络中唯一定位一个服务器上的某个资源例如:http://username:password@baike.baidu.com/item/HTML/97...
2020-03-20 17:04:22 543
原创 进程控制
进程创建fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。#include <unistd.h>pid_t fork();//返回值:子进程中返回0,父进程返回子进程id,出错返回-1进程调用fork,当控制转移到内核中的fork代码后,内核做:分配新的内存块和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加...
2020-03-19 13:44:12 96
原创 socket编程——tcp通信
tcp通信流程:面向连接,可靠传输,面向字节流客户端(client):创建套接字绑定地址信息(不推荐主动)向服务端发出连接请求收 / 发数据关闭套接字服务端(server):创建套接字——在内核创建socket结构体与网卡建立联系为套接字绑定地址信息——告诉操作系统哪些数据交给我处理—放到我的接收缓冲区开始监听——告诉操作系统可以开始接收哭护短的连接请求—客户端与服务端进...
2020-03-17 15:00:52 389
原创 插入排序
插入排序(Insertion sort)是一种简单直观且稳定的排序算法。如果有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,算法适用于少量数据的排序,时间复杂度O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好
2020-03-12 16:54:10 77
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人