智能指针
智能指针是一种在编程中管理动态内存资源的对象。它封装了原始指针(raw pointer),并提供额外的功能,例如自动释放资源、避免内存泄漏和管理对象的生命周期。智能指针广泛用于需要动态分配内存的语言(如 C++),通过 RAII(Resource Acquisition Is Initialization)原则实现内存管理。 在 C++ 中,智能指针主要在 <memory> 头文件中定义,包括以下几种类型: 1. std::unique_ptr 特点: 独占所有权(一个对象只能有一个 unique_ptr 拥有它)。 不可复制,但可以通过 std::move 转移所有权。 适合需要明确单一所有权的场景。 用法: 12345678#include <memory>#include <iostream>int main() { std::unique_ptr<int> ptr = std::make_unique<int>(42); // 创建智能指针 std::cout <<...
Lambda表达式
在 C++ 中,Lambda 表达式是一种轻量级的函数对象(或匿名函数),可以在代码中定义并直接使用。它是从 C++11 引入的功能,常用于需要定义短小函数的场景,比如多线程、STL 算法或回调函数中。 1. Lambda 表达式的基本语法123[捕获列表](参数列表) -> 返回类型 { 函数体}; **捕获列表**:定义 lambda 可以捕获哪些变量,以及如何捕获(按值或按引用)。 **参数列表**:和普通函数类似,定义函数的参数。 **返回类型**:可选,通常由编译器自动推断。 **函数体**:函数的逻辑部分。 2. Lambda 表达式的基本示例12345678910111213141516171819#include <iostream>#include <vector>#include <algorithm>int main() { // 最简单的 Lambda auto lambda = [] { std::cout <<...
c++11新特性之emplace
emplace 是 C++ 中标准库(STL)提供的一种高效的元素插入方式,常用于容器(如 std::vector, std::map, std::unordered_map 等)中。emplace 通过直接在容器内部构造元素,避免了不必要的拷贝或移动操作,从而提高了性能。 emplace 和 insert 的区别 **insert**:将一个已构造的对象插入到容器中。通常需要通过拷贝或移动构造将元素插入容器。 123std::vector<int> vec;int x = 5;vec.insert(vec.end(), x); // 插入时会发生一次拷贝构造 **emplace**:直接在容器内部构造元素,避免了额外的拷贝或移动操作。emplace 接受构造元素所需的参数,然后直接在容器中构造该元素。 12std::vector<int> vec;vec.emplace_back(5); // 在容器内部构造元素,避免拷贝 为什么使用 emplace? 避免不必要的拷贝或移动: insert...
c++中的I/O流
在 C++ 中,输入输出(I/O)库提供了流(stream)的状态管理功能。每个流对象(如 cin, cout, ifstream, ofstream 等)都有一个与之相关的状态,标志着当前流的操作是否成功。流的状态主要通过流的条件标志(flags)来表示。这些标志通常用于检查流是否处于有效的状态,以便在进行输入输出操作时处理异常或错误。 流的条件状态(Flags)流的条件状态通过 ios 类中的几个成员标志进行管理,这些标志包括: **good()**:流是否处于正常状态,即没有发生任何错误。 **eof()**:流是否已经到达文件末尾。 **fail()**:流是否遇到输入/输出错误。 **bad()**:流是否发生严重错误,导致无法继续读取或写入。 这些状态标志可以通过流对象的方法访问,通常用于判断流的状态。 流的状态检查1. good() good() 返回 true 如果流没有遇到任何错误,输入输出操作可以继续进行。它相当于检查流的状态是否为 ios::goodbit。 123if (cin.good()) { cout...
四种强制类型转换操作符
在 C++ 中,有四种强制类型转换操作符,分别是: static_cast dynamic_cast const_cast reinterpret_cast 这四种类型转换都属于强制类型转换,它们的应用场景和功能有所不同。下面详细介绍每一种。 1. static_caststatic_cast 用于在类型之间进行转换时,进行编译时类型检查。它适用于转换那些在语义上兼容的类型,例如基本数据类型、类之间的转换等。 用法: 类之间的转换(如父类和子类的转换)。 基本数据类型之间的转换。 指针类型之间的转换,当有继承关系时,可以转换指向基类的指针和指向派生类的指针。 示例:12345678910111213141516171819202122232425#include <iostream>class Base {public: virtual void show() { std::cout << "Base" << std::endl; }};class Derived :...
c++中的四种命名的强制类型转换
在 C++ 中,有四种强制类型转换操作符,分别是: static_cast dynamic_cast const_cast reinterpret_cast 这四种类型转换都属于强制类型转换,值得一提的是其实这四种强制转换都是较为危险的,很容易出现错误,尽量少用 1. static_caststatic_cast 用于在类型之间进行转换时,进行编译时类型检查。 它适用于转换那些在语义上兼容的类型,例如基本数据类型、类之间的转换等。 任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast 用法: 类之间的转换(如父类和子类的转换)。 基本数据类型之间的转换。 指针类型之间的转换,当有继承关系时,可以转换指向基类的指针和指向派生类的指针。 示例:12345678910111213141516171819202122232425#include <iostream>//类之间的转换class Base {public: virtual void show() { std::cout <<...
指向常量的指针与常量指针
好久没有更新博客了,与最近考试多有关,也与个人怠惰有关 今天的内容是指向常量的指针(pointer to const)与指针常量(const pointer),这是昨天在阅读《c++ primer》中重新理解的内容,有了些许新的感悟,趁热打铁,发在博客上 在讲那两个之前,先说一下const与对常量的引用(reference to const)const修饰词使用const修饰词修饰的变量,即常量,是必须初始化的,且初始化后不能修改其值 初始化时除了用如下方法 1const int a=1; 同样可以用非常量但同类型的值进行赋值(拷贝) 123int a=1;const int b=a;a=b; const修饰的对象在编译时直接替换,类似define,即提前将所有出现其的位置替换成对应的数值,不申请额外空间 以下场景除外(都要等具体的值才能初始化) 12const int a =fun();const int &b=c; 同时const对象仅在文件内部有效,要实现在一个文件中定义,在多个文件中声明并使用,要用extern...
几种排序
冒泡排序(Bubble Sort)是一种简单直观的排序算法,其基本思想是通过多次遍历待排序的序列,比较相邻元素并交换它们的位置,使较大的元素逐渐“冒泡”到序列的末尾。尽管效率较低,但它是介绍排序算法时常用的例子之一,适合对小规模数据的排序。 冒泡排序的原理 从序列的第一个元素开始,依次比较相邻的两个元素。如果前面的元素大于后面的元素,就交换它们的位置。 每次遍历后,最大的元素会被交换到当前未排序部分的末尾。 对未排序部分重复上述过程,直到没有元素需要交换为止。 冒泡排序的特点 时间复杂度: 最坏情况: $O(n^2)$(数组逆序) 最好情况: $O(n)$(数组已经有序,只需一次遍历) 平均情况: $O(n^2)$ 空间复杂度: $O(1)$(只需常数级的额外空间) 稳定性:起泡排序是稳定的排序算法,即相同的元素在排序后不会改变相对顺序。 冒泡排序的实现C++ 实现12345678910111213141516171819202122232425262728293031323334353637383940414243#include...
前缀表与KMP算法
KMP(Knuth-Morris-Pratt)算法是一种用于字符串匹配的高效算法,它能够在文本串中查找模式串出现的位置。KMP算法的核心在于避免重复比较字符,从而提高匹配效率。 KMP算法的基本思路 预处理模式串:通过构建一个“部分匹配表”(或称为“失配表”),在模式串中记录每个位置的最长可匹配前缀长度。 匹配过程:利用部分匹配表,在匹配失败时,根据前缀信息跳过不必要的比较,从而加速匹配过程。 部分匹配表(LPS数组)LPS(Longest Prefix Suffix)数组用于存储模式串的每个前缀的最长相等前后缀的长度。具体构建方式如下: **LPS[i]**:表示模式串的前缀(pattern[0] 到...
leetcode心得
1.对于复杂条件的题,看能不能将条件简化,比如通过排序让题目简单,比如去掉多余空格,让后序算法简化操作 2.双指针对于局部的变化有奇效