当前位置: 首页 > news >正文

C++学习 虚函数,容器

一、虚函数

  1. 虚函数是C++中的一种函数,允许子类重写父类中的函数,以便在运行时通过基类指针或引用调用子类的函数实现。
  2. 虚函数的主要作用是实现多态性,这使得基类指针或引用可以根据实际指向的对象类型调用不同的函数实现。
  3. 具体用法
  • 虚函数的声明:在基类中使用关键字 virtual 声明函数,告诉编译器这个函数是虚函数。
class Base {
public:virtual void display() {std::cout << "Base display" << std::endl;}
};
  • 子类重写虚函数:子类可以通过定义与基类相同签名的函数来重写虚函数。重写的函数不需要再次使用 virtual 关键字,但通常会标记为 override 来确保它确实是对基类虚函数的重写。
class BaseChild1 : public Base {public:void display() override{std::cout << "BaseChild1 display" << std::endl;}
};class BaseChild2 : public Base {public:void display() override{std::cout << "BaseChild2 display" << std::endl;}
};
  1. 多态性
  • 如果通过基类指针或引用调用一个虚函数,实际调用的函数取决于对象的实际类型,而不是指针或引用的类型。
  • 虚函数实现的是动态多态性,即在运行时决定调用哪个函数。
  • 相比之下,模板和函数重载则是静态多态性的实现形式,它们在编译时决定调用哪个函数。两者各有优缺点,应该根据具体需求选择使用哪种多态性。
 Base *ptr = new BaseChild1;ptr->display();std::cout << "------------------------------------" << std::endl;Base *ptr1 = new BaseChild2;std::cout << "------------------------------------" << std::endl;Base *ptr2 = new Base;ptr2->display();
  1. 虚函数表V-Table
  • 编译器会为包含虚函数的类生成一个虚函数表(V-Table),其中包含指向虚函数实现的指针。
  • 每个包含虚函数的对象都会有一个指向其所属类的V-Table的指针。
  • 在调用虚函数时,程序会通过这个表查找函数的实际实现。
  1. 析构函数的虚拟化:
    如果一个类有虚函数,通常也需要将析构函数声明为虚函数,以确保在删除对象时,调用正确的析构函数(特别是通过基类指针删除子类对象时)。
  2. 纯虚函数
  • 如果一个虚函数在基类中没有定义实现(即为0),那么这个函数就是纯虚函数。
class Base {
public:virtual void show() = 0; // 纯虚函数
};
  • 定义了纯虚函数的类称为抽象类,它不能实例化,只能用作派生类的基类。
  • 派生类必须实现所有继承的纯虚函数,否则派生类本身也将成为抽象类。
  1. 虚函数在构造函数和析构函数中的行为
  • 在构造函数和析构函数中,虚函数的调用行为有所不同。在构造函数中,虚函数的调用是静态绑定的,即调用的是当前类的函数版本,而不是派生类的版本。
  • 这意味着在基类构造函数中调用虚函数时,即使对象类型是派生类,调用的也是基类中的函数版本。
class Base {
public:Base() {show(); // 调用 Base::show()}virtual void show() {std::cout << "Base show" << std::endl;}
};class Derived : public Base {
public:void show() override {std::cout << "Derived show" << std::endl;}
};int main() {Derived obj; // 调用 Base::show() 而不是 Derived::show()return 0;
}
  1. 多重继承与虚函数
  • 多重继承:在多重继承中,如果基类包含虚函数,虚函数表的管理会变得更加复杂。
    在这种情况下,每个继承的路径可能会生成一个单独的虚函数表。
class Base1 {
public:virtual void show() { std::cout << "Base1 show" << std::endl; }
};class Base2 {
public:virtual void display() { std::cout << "Base2 display" << std::endl; }
};class Derived : public Base1, public Base2 {
public://Derived 类会拥有两个虚函数表,一个用于 Base1,另一个用于 Base2,以正确处理多重继承中虚函数的调用。void show() override { std::cout << "Derived show" << std::endl; }void display() override { std::cout << "Derived display" << std::endl; }
};

二、auto关键字

  • 在 C++ 中,auto 关键字用于自动推导变量的类型,编译器会根据变量的初始值推断出其类型。这样可以让代码更加简洁,减少显式类型声明的冗余。
  • 常量类型:auto 会忽略 const 和 volatile 修饰符,除非显式声明。
std::vector<int>::iterator it = vec.begin(); // 传统写法
auto it = vec.begin();                      // 使用 auto
auto result = func();  // 由函数返回值推断类型
//避免显式类型错误:有时显式类型声明可能会出错,特别是使用模板时,auto 可以确保类型推导正确。const int a = 5;
auto b = a;       // b 的类型是 int 而不是 const int
const auto c = a; // c 的类型是 const intint x = 10;
auto y = x;   // y 是 x 的副本,y 和 x 没有关系
y = 20;       // 修改 y,不影响 x
std::cout << "x = " << x << ", y = " << y << std::endl;  // 输出 x = 10, y = 20auto& z = x;  // z 是 x 的引用
z = 30;       // 修改 z,相当于修改 x
std::cout << "x = " << x << ", z = " << z << std::endl;  // 输出 x = 30, z = 30int* ptr = &a;  // 指针 ptr 指向 a
int& ref = a;   // 引用 ref 绑定到 a
  • 推导规则
    左值引用:如果初始值是左值引用,auto 推导的结果是值类型,而不是引用类型。如果希望推导为引用,可以显式加上 &。
int x = 10;
auto y = x;   // y 是 int 类型的副本
auto& z = x;  // z 是对 x 的引用

三、顺序容器(头文件就是容器本身)

  • 顺序容器是C++标准模板库(STL)中一种重要的容器类型,专门用于存储和管理元素的有序集合。
  • 顺序容器以线性方式组织数据,元素按插入顺序排列,用户可以通过迭代器或索引来访问它们。
主要的顺序容器
  • 在C++中,顺序容器(Sequence Containers)是一类存储元素的容器,其元素按插入顺序存储。这类容器的主要特点是元素的存储顺序与插入顺序一致,提供了随机访问或线性遍历的能力。
  1. std::vector
    • 特点:
      - 动态数组,支持随机访问。
      - 支持高效的尾部插入和删除
      - 动态扩展容量
    • 适用场景:
      - 需要频繁的随机访问。
      - 需要在末尾频繁插入和删除元素。
  2. std::deque
    • 特点:
      - 双端队列,支持从两端快速插入和删除,元素不一定存储在连续的内存中。
    • 适用场景
      - 适合需要频繁在两端插入或删除元素的场景。
  3. std::list
    • 双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快。
  4. std::forward_list
    • 特点:
      • 单向链表,每个元素只包含指向下一个元素的指针,内存使用更小。
    • 适用场景
      • 适合内存非常有限并且只需要单向遍历的场景。
  5. std::array
    • 特点
      • std::array 是 C++11 引入的一个定长数组容器,存储在栈上,大小在编译时就确定。
      • 元素存储在连续的内存中,类似于 std::vector,但其大小是固定的,不能动态调整。
      • 由于大小在编译时就确定,因此更适合存储在栈上,而不是堆上。
      • 不提供内存的动态分配,因此比 std::vector 更加轻量。
    • 适用场景
      • 适合大小固定且不需要动态增长的数组,如对性能和内存开销有严格要求时。
  6. std::string
    • 特点:std::string 是一个用于存储字符序列的容器,实质上是动态的字符数组,内部实现类似于 std::vector<char>,但提供了更多处理字符串的功能。
    • 适用场景:适合处理文本数据和字符序列,广泛用于字符串处理、文本解析等场景。
顺序容器公有操作(私有操作繁多,用时再查)

1.定义

std::vector<int> vec;//int也可以换成其他数据类型
std::deque<int> dq;
std::list<int> lst;
std::array<int,5> arr;
std::string str;
  1. 初始化操作类比
// 1. 默认构造
std::vector<int> vec1;  // 创建一个空的 vector// 2. 指定大小构造(所有元素初始化为默认值)
std::vector<int> vec2(5);  // 创建一个大小为 5 的 vector,元素初始化为 0// 3. 指定大小和初始值的构造
std::vector<int> vec3(5, 10);  // 创建一个大小为 5 的 vector,所有元素初始化为 10// 4. 使用初始值列表构造
std::vector<int> vec4 = {1, 2, 3, 4, 5};  // 使用列表初始化 vector
  1. 元素访问
vec[2] = 10;  // 访问 vector 的第 3 个元素
int val = vec.at(2);  // 安全访问 vector 的第 3 个元素,越界时抛出异常
int first = vec.front();//返回容器中第一个元素。
int last = vec.back();//返回容器中最后一个元素(std::array 除外,其他容器支持)。
  1. 容量相关操作
size_t n = vec.size();  // 返回元素数量
bool is_empty = vec.empty();  // 如果容器为空则返回 true
size_t max_n = vec.max_size();//返回容器可能存储的最大元素数量。
  1. 修改容器内容
vec.clear();  // 删除所有元素
vec.insert(vec.begin() + 1, 20);  // 在第二个位置插入 20
vec.erase(vec.begin()+0);  // 删除第一个元素
vec.push_back(10);  // 在末尾插入 10(std::array 不支持)
vec.pop_back();  // 移除末尾元素(std::array 不支持)
vec1.swap(vec2);  // 交换 vec1 和 vec2 的内容
迭代器
  • 在 C++ 中,迭代器(iterator)是一种用于遍历容器中元素的对象,类似于指针
  • 所有标准容器(如 std::vector、std::deque、std::list、std::array、std::string 等)都提供了迭代器,用来顺序访问容器中的元素。
  • 迭代器的操作方式比较统一,但不同的容器支持的迭代器类型和特性可能有所不同。
  1. 常见的迭代器类型
迭代器用途
iterator用于指向容器中的元素,支持读写操作。
const_iterator用于指向容器中的元素,支持只读操作。
reverse_iterator反向迭代器,用于倒序遍历容器。
const_reverse_iterator只读的反向迭代器。
begin() 和 end()返回迭代器,分别指向容器的第一个元素和尾后元素(即最后一个元素的下一个位置)。
rbegin() 和 rend()返回反向迭代器,分别指向容器的最后一个元素和第一个元素之前的位置。
  1. 迭代器的使用示例
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用 iterator 遍历 vector//std::vector<int>::iterator 表明迭代器的类型和谁的迭代器。for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";  // 输出元素}// 使用 const_iterator 进行只读访问for (std::vector<int>::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) {std::cout << *it << " ";  // 只能读取元素}// 使用 reverse_iterator 反向遍历for (std::vector<int>::reverse_iterator it = vec.rbegin(); it != vec.rend(); ++it) {std::cout << *it << " ";  // 输出元素}
}
  1. 迭代器常见操作
  • 解引用 (*it):访问迭代器指向的元素。
  • 前进 (++it):将迭代器移动到下一个元素。
  • 后退 (–it):将迭代器移动到前一个元素(双向迭代器才支持)。
  • 比较 (it == end()):检查迭代器是否到达容器的末尾。

泛型算法

  • 泛型算法是指可以应用于多种数据结构或容器类型的算法,通常通过模板实现,允许编写与具体类型无关的通用代码
  • 在 C++ 中,泛型算法是通过标准模板库(STL)中的算法库实现的,这些算法可以与各种容器(如 vector、list、deque 等)结合使用。
  • 特点:独立于容器,基于迭代器,模板实现。
  • STL 中提供了许多常用的泛型算法,包括排序、查找、变换、合并等操作。通过迭代器和模板,STL 中的算法能够处理任意类型的容器或范围。
  • 头文件: #include 或者 #include (算数相关)
  • 迭代器是 STL 容器和算法之间的桥梁。所有的泛型算法都使用迭代器来访问容器的数据,而不是直接操作容器。这种设计使得算法可以独立于容器,变得非常灵活。
常用的泛型算法
  1. 非修改序列算法:不修改容器内容,只读取和比较元素。
    示例:std::find、std::count、std::accumulate。
  2. 修改序列算法:修改容器的内容或结构。
    示例:std::copy、std::fill、std::replace。
  3. 排序和相关算法:对元素进行排序或重新排列。
    示例:std::sort、std::stable_sort、std::partial_sort。
  4. 排序操作算法:基于排序的查找和集合操作。
    示例:std::binary_search、std::merge、std::includes。
  5. 数值算法:对数值序列进行计算。
    示例:std::accumulate、std::inner_product、std::adjacent_difference。
泛型算法的使用示例
// 使用 std::find 查找值为 3 的元素auto it = std::find(vec.begin(), vec.end(), 3);
// 使用 std::sort 对元素进行排序std::sort(vec.begin(), vec.end());
// 使用 std::copy 将元素从 src 复制到 deststd::copy(src.begin(), src.end(), dest.begin());
// 使用 std::replace 将值为 2 的元素替换为 5std::replace(vec.begin(), vec.end(), 2, 5);
based for 循环
  • 基于范围的 for 循环
  • 基于范围的 for 循环(Range-based for loop)是 C++11 引入的一种简洁的语法,用于遍历容器或序列中的元素。
  • 相比于传统的 for 循环,基于范围的 for 循环更简单、可读性更高,并且减少了迭代器或索引的使用。
  • 语法
for (declaration : range_expression) {// loop body
}
参数:declaration:循环体中每次迭代时用来接收当前元素的变量声明。可以是变量的值、引用或常量引用。range_expression:一个可遍历的范围或容器,比如数组、std::vector、std::array、std::list 等。还可以是具有 begin()end() 方法的自定义类。
  • 使用例子范例
#include <iostream>
#include <vector>
int main() {int arr[] = {1, 2, 3, 4, 5};std::vector<int> vec = {10, 20, 30, 40, 50};// 基于范围的 for 循环遍历数组for (int x : arr) {std::cout << x << " ";}// 基于范围的 for 循环遍历 vectorfor (int x : vec) {std::cout << x << " ";}// 使用引用遍历,修改 vector 中的值for (int& x : vec) {x += 10;  // 修改元素值}for (int x : vec) {std::cout << x << " ";}return 0;
}
  • 使用 const 来防止修改元素
#include <iostream>
#include <vector>int main() {std::vector<int> vec = {10, 20, 30, 40, 50};// 使用 const 引用遍历,防止修改元素for (const int& x : vec) {std::cout << x << " ";}return 0;
}
总结
  • 泛型算法允许我们编写通用代码,能够适用于不同的容器和数据类型。
  • C++ STL 中提供了丰富的泛型算法,如查找、排序、变换、复制等操作。
  • 泛型算法通过迭代器来与容器交互,使得它们与具体容器解耦,能够处理不同类型的容器。
  • 通过使用模板、迭代器和 Lambda 表达式,我们可以轻松地自定义和扩展泛型算法。

关联容器

  • 关联容器(Associative Containers)是C++标准模板库(STL)中用于高效存储和检索键-值对的数据结构。
  • 与顺序容器(如vector、deque等)不同,关联容器主要依赖键(也就是关键字)来访问元素,而不是通过索引。
主要的关联容器类型
容器类型解释
std::set用于存储唯一元素的有序集合,基于平衡二叉树实现。插入、删除、查找的时间复杂度为O(log n)。
std::map键值对的有序集合,其中每个键唯一,且按键有序排列。插入、删除、查找操作的时间复杂度同样为O(log n)。
std::multiset与set类似,但允许存储重复元素。
std::multimap类似于map,但允许一个键对应多个值。
无序关联容器
std::unordered_set存储唯一元素的无序集合,底层基于哈希表实现。插入、删除、查找的时间复杂度为O(1)(最优情况下)。
std::unordered_map键值对的无序集合,基于哈希表。键值对无序排列,插入、删除、查找的时间复杂度为O(1)(最优情况下)。
std::unordered_multiset与unordered_set类似,但允许存储重复元素。
std::unordered_multimap类似于unordered_map,但允许一个键对应多个值。
关联容器用法
  1. std::set
    std::set 用于存储唯一元素,元素默认按升序排列。
    构造
std::set<int> mySet;  // 默认构造一个空集合
std::set<int> mySet = {10, 20, 30};  // 用初始化列表构造

插入

mySet.insert(40);  // 插入元素40,返回一个pair,第一个值是迭代器,第二个值是是否插入成功

删除

mySet.erase(10);  // 删除值为10的元素
mySet.clear();    // 清空集合

查找

auto it = mySet.find(20);  // 返回指向值为20的迭代器,如果未找到则返回end()
bool contains = mySet.count(20) > 0;  // 判断是否存在20
  1. std::map
  • std::map存储键值对,每个键都是唯一的,键默认按升序排列。
  • .first是第一个键,.second是第二个值
    构造
std::map<int, std::string> myMap;  // 空的map
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}};  // 用初始化列表构造

插入

myMap[3] = "three";  // 插入键值对{3, "three"}
myMap.insert({4, "four"});  // 插入键值对{4, "four"}

删除

myMap.erase(1);  // 删除键为1的元素
myMap.clear();   // 清空所有键值对

查找

auto it = myMap.find(2);  // 查找键为2的元素,返回迭代器
if (it != myMap.end()) {std::cout << "Key 2 maps to " << it->second << std::endl;
}

遍历

for (const auto &pair : myMap) {std::cout << pair.first << ": " << pair.second << std::endl;  // 输出所有键值对
}
  1. 其余的都是在这两个基础上推展出来的,无非就是无序,重复

相关文章:

C++学习 虚函数,容器

一、虚函数 虚函数是C中的一种函数&#xff0c;允许子类重写父类中的函数&#xff0c;以便在运行时通过基类指针或引用调用子类的函数实现。虚函数的主要作用是实现多态性&#xff0c;这使得基类指针或引用可以根据实际指向的对象类型调用不同的函数实现。具体用法 虚函数的声…...

MacTalk 测评通义灵码,如何实现“微信表情”小功能?

作者&#xff1a;池建强&#xff0c;墨问西东创始人 前段时间&#xff0c;我写了篇墨问研发团队放弃 GitHub Copilot 的文章&#xff0c;没想到留言区一些读者推荐我们试试通义灵码&#xff0c;说它效果很不错。我呢&#xff0c;一直没腾出时间折腾。 直到月中时&#xff0c;…...

Canvas Confetti - 免费开源的五彩纸屑飞舞特效的 JS 库,多用于在网页上实现欢乐庆祝的场景

今天看科技周刊看到的一个酷炫的动效库&#xff0c;使用简单&#xff0c;视觉效果很好&#xff0c;推荐给大家。 Canvas Confetti 是一个基于 JavaScript 的特效动画库&#xff0c;可以在网页界面上轻松地实现五彩纸屑飞舞的庆祝场景特效。这个特效库封装了几种酷炫的特效&…...

[数据集][目标检测]智慧牧场猪只检测数据集VOC+YOLO格式16245张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;16245 标注数量(xml文件个数)&#xff1a;16245 标注数量(txt文件个数)&#xff1a;16245 标…...

GS-SLAM论文阅读笔记--LoopSplat

介绍 这篇文章看标题是解决GS-SLAM回环检测的&#xff0c;GS-SLAM回环检测之前文章很少&#xff0c;但他对于SLAM又很重要&#xff0c;确实值得阅读一番。而且这些作者的学校又是很厉害的。 文章目录 介绍1.背景介绍2.关键内容2.1 Gaussian Splatting SLAM2.2 Gaussian Splat…...

Mysql数据库表结构迁移PostgreSQL

1、背景&#xff1a; 公司本来用的数据库都是mysql&#xff0c;为了国产化适配兼容pg和dm。dm提供了数据迁移工具&#xff0c;可以直接做数据迁移&#xff0c;生成脚本之后在其他环境执行。但是pg貌似没有工具能直接用。navicat由于版权问题公司也用不了。pgloader使用总是有问…...

店匠科技携手Stripe共谋电商支付新篇章

在全球电商行业蓬勃发展的背景下,支付环节作为交易闭环的核心,其重要性日益凸显。随着消费者对支付体验要求的不断提高,以及跨境电商的迅猛发展,支付市场正经历着前所未有的变革与挑战。在这一充满机遇与竞争的领域,店匠科技(Shoplazza)凭借其创新的嵌入式支付解决方案—— Sho…...

大众(奥迪)汽车继电器编号对照表

数字功能放大器零件编号1化油器进气歧管加热器40a1719063832燃油泵(CE1 MK1 Golf 和 Early Rocco/cabrio K-Jet,无转速限制器)-443906059A 321906059D/E3燃油泵(CE1 MK1 Golf 和 Early Rocco/cabrio K-Jet,无转速限制器)-4439060594安全带警告继电器5早期 MFA 时钟的换档…...

《佛脚闪卡watch》——Apple Watch上的高效学习助手

在快节奏的生活环境中&#xff0c;时间管理成为了学习成功的关键因素之一。**《佛脚闪卡watch》**是一款专为Apple Watch设计的应用程序&#xff0c;旨在帮助学生和自学者更高效地利用碎片时间进行学习。无论是等待公交、散步还是短暂休息&#xff0c;您都可以随时随地进行复习…...

六、桥接模式

桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;旨在将抽象与实现分离&#xff0c;使得两者可以独立变化。通过使用桥接模式&#xff0c;可以避免在多个维度上进行继承&#xff0c;降低代码的复杂度&#xff0c;从而提高系统的可扩展性。 组成…...

Vue eslint 语法检测问题

1. 修改 prettier 配置文件 确保你的项目中有 .prettierrc 配置文件&#xff0c;并在其中添加或修改 endOfLine 设置为 lf&#xff0c;确保统一使用 LF 换行符。 在 .prettierrc 文件中添加&#xff1a; {"endOfLine": "lf" }2. 修改 .editorconfig 文件…...

QT Creater实现国庆节主题项目【0基础完成版】

本文适用对象 想要学习qt creater的小白;想要学习c++制作软件的编程爱好者。可以先下载这篇博客绑定的资源,然后一边操作,一边学习,会更高效~0. 创建初始项目 一步步来操作吧,首先下载qt creter,之前发布过相关资源,大家直接查找下载,或者自行下载。 1. 初始代码 mai…...

Qt 加载 WPS 时提示要登录

项目中Qt加载word时 默认用wps打开word文档 程序一运行老是提示要立即登录 看着很烦 可以按下面的方法去掉这个烦人的东西 在下面的项目中新建字符串enableforceloginforfirstinstalldevice&#xff0c;值为false即可。...

vue3的el-tree的default-checked-keys无法勾选的问题解决

前言:有些树形控件是需要默认勾选的 但是请求后渲染不显示 刷新外部的key值也没有用 看了一下文档 我们使用自带的方法来解决 <el-treenode-key"id":data"state.parentMenuList":default-checked-keys"state.checkIdList":check-on-click-n…...

class 5: vue.js 3 v-model和表单输入

v-model是Vue.js 3中用于实现双向绑定的重要指令&#xff0c;双向绑定就是对于数据的修改会映射回UI组件上&#xff0c;同时对于UI组件上数据的变更也会映射回底层数据当中&#xff0c;v-model会根据控件的类型自动选取正确的方法来更新元素v-model底层实现的原理实际上是v-bin…...

了解一下HTTP 与 HTTPS 的区别

介绍&#xff1a; HTTP是超文本传输协议。规定了客户端&#xff08;通常是浏览器&#xff09;和服务器之间如何传输超文本&#xff0c;也就是包含链接的文本。通常使用TCP【1】/IP协议来传输数据&#xff0c;默认端口为80。 HTTPS是超文本传输安全协议&#xff0c;具有CA证书。…...

Opencv中的直方图(1)计算反向投影直方图函数calcBackProject()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算直方图的反向投影。 cv::calcBackProject 函数计算直方图的反向投影。也就是说&#xff0c;类似于 calcHist&#xff0c;在每个位置 (x, y)…...

VUE3项目的几种创建方式

文章目录 1.使用 Vue CLI (Vue Command Line Interface):2.使用 Create Vue App:3.使用 Vite:4.使用图形用户界面 (GUI):5.纯手工搭建6.基于模板创建: 1.使用 Vue CLI (Vue Command Line Interface): Vue CLI 是官方推荐的方式来快速搭建 Vue 项目的基础结构。命令&#xff1a…...

VBA进行excel坐标转换

在Excel里利用坐标绘图时&#xff0c;可以比较容易想到采用数据透视表&#xff0c;但是数据透视表生成的图不可更改&#xff0c;因此本案例采用VBA进行坐标变换而不改变原始值来转换图像&#xff0c;即实现图像的左右翻转和上下翻转&#xff0c;如下图所示&#xff0c;选择map的…...

使用pytorch深度学习框架搭建神经网络

简介 现在主流有两个框架pytorch和TensorFlow,本文主要介绍pytorch PyTorch&#xff1a;由 Facebook 的人工智能研究小组开发和维护。PyTorch 以其动态计算图&#xff08;Dynamic Computational Graph&#xff09;和易用性著称&#xff0c;非常适合研究人员和开发者进行实验和…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

路由基础-路由表

本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中&#xff0c;往往存在多个不同的IP网段&#xff0c;数据在不同的IP网段之间交互是需要借助三层设备的&#xff0c;这些设备具备路由能力&#xff0c;能够实现数据的跨网段转发。 路由是数据通信网络中最基…...

算法250609 高精度

加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...

qt 双缓冲案例对比

双缓冲 1.双缓冲原理 单缓冲&#xff1a;在paintEvent中直接绘制到屏幕&#xff0c;绘制过程被用户看到 双缓冲&#xff1a;先在redrawBuffer绘制到缓冲区&#xff0c;然后一次性显示完整结果 代码结构 单缓冲&#xff1a;所有绘制逻辑在paintEvent中 双缓冲&#xff1a;绘制…...