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

C++ 迭代器之旅(Journey of Iterators)

C++ 迭代器之旅(Journey of Iterators)

  • 一、引言(Introduction)
    • C++ Iterator模板库简介(Overview of C++ Iterator Template Library)
    • Iterator的重要性和作用(The Importance and Role of Iterators)
  • 二、C++ Iterator模板库详解(In-depth Explanation of the C++ Iterator Template Library)
    • Iterator概述及分类(Overview and Classification of Iterators)
    • Iterator的基本操作(Basic Operations of Iterators)
    • 实例讲解(Examples and Explanations)
      • a. 示例1:使用输入迭代器读取数据(Example 1: Reading Data with Input Iterators)
      • b. 示例2:使用输出迭代器输出数据(Example 2: Writing Data with Output Iterators)
      • c. 示例3:前向迭代器的应用场景(Example 3: Application Scenarios of Forward Iterators)
      • d. 示例4:双向迭代器与随机访问迭代器的比较与应用(Example 4: Comparison and Application of Bidirectional Iterators and Random Access Iterators)
  • 三、C++ Iterator模板库在容器中的应用(Application of C++ Iterator Template Library in Containers)
    • 顺序容器(Sequential Containers)
    • 关联容器(Associative Containers)
    • 无序容器(Unordered Containers)
  • 四、C++ Iterator模板库的最佳实践与注意事项(Best Practices and Precautions for C++ Iterator Template Library)
    • 迭代器失效的问题(Iterator Invalidating Issues)
    • 迭代器适配器的使用(Using Iterator Adapters)
    • 注意事项与常见错误(Precautions and Common Mistakes)
  • 五、总结(Conclusion)
    • C++ Iterator模板库的重要性(Importance of C++ Iterator Template Library)
    • 学习与成长(Learning and Growth)

一、引言(Introduction)

在本篇文章中,我们将简要介绍C++迭代器模板库,以及迭代器在C++编程中的重要性和作用。迭代器是C++标准模板库(STL)的一个核心组件,它允许程序员以一种简洁、通用和高效的方式操作容器和数据结构。

C++ Iterator模板库简介(Overview of C++ Iterator Template Library)

C++迭代器模板库是C++标准模板库(STL)的一部分,它提供了一种统一的接口来访问和操作各种容器中的元素。迭代器可以被视为一个通用的指针,它能够在不同类型的容器之间进行无缝转换。这意味着,无论你正在使用向量(vector)、列表(list)还是其他STL容器,迭代器都可以帮助你以相同的方式访问和操作数据。

迭代器主要分为五种类型,分别是输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。每种类型的迭代器都有其特定的操作和限制。例如,输入迭代器仅用于读取容器中的元素,而输出迭代器仅用于写入容器中的元素。

Iterator的重要性和作用(The Importance and Role of Iterators)

迭代器在C++编程中具有重要的作用,主要表现在以下几个方面:

a. 通用性:迭代器为访问和操作不同类型的容器提供了统一的接口。这使得程序员可以编写与容器类型无关的通用代码,提高了代码的可重用性。

b. 抽象性:迭代器将访问和操作容器元素的具体细节抽象出来,使得程序员可以专注于实现程序的逻辑,而不需要关心底层容器的实现细节。

c. 高效性:迭代器的设计使得许多操作可以在编译时进行优化,从而提高了程序运行时的性能。

d. 扩展性:通过自定义迭代器,程序员可以轻松地为自己的数据结构和类定义访问和操作元素的方法,使其与STL容器具有相同的易用性。

总之,迭代器在C++编程中起着至关重要的作用,它提高了代码的通用性、抽象性、高效性和扩展性。通过深入了解和熟练使用迭代器,程序员可以更加高效地设计和实现C++程序。

二、C++ Iterator模板库详解(In-depth Explanation of the C++ Iterator Template Library)

Iterator概述及分类(Overview and Classification of Iterators)

C++ Iterator 模板库是 C++ 标准库中的一个重要组成部分,它允许对容器(如 vector、list、set 等)中的元素进行遍历和操作。迭代器的概念类似于指针,但它更为通用,可以与各种容器一起使用。迭代器有五种基本类型,分别为输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。

  1. 输入迭代器(Input Iterators): 输入迭代器主要用于从容器中读取元素。它支持自增操作(++)和解引用操作( *)。输入迭代器只能从前向后移动,且只能进行单遍遍历。
  2. 输出迭代器(Output Iterators): 输出迭代器主要用于将数据写入容器。它也支持自增操作(++)和解引用操作( *),但解引用后只能用于赋值。与输入迭代器一样,输出迭代器只能从前向后移动,且只能进行单遍遍历。
  3. 前向迭代器(Forward Iterators): 前向迭代器继承了输入迭代器和输出迭代器的特性,支持对容器中的元素进行读写操作。前向迭代器也只能从前向后移动,但它可以进行多次遍历。
  4. 双向迭代器(Bidirectional Iterators): 双向迭代器在前向迭代器的基础上增加了向后移动的能力,即支持自减操作(–)。双向迭代器可以用于 list、set 和 map 等容器。
  5. 随机访问迭代器(Random Access Iterators): 随机访问迭代器提供了最高级别的功能。除了支持前向迭代器和双向迭代器的所有操作外,还支持通过整数索引直接访问容器中的任意元素。随机访问迭代器可以用于 vector 和 deque 等容器。

这些迭代器类型定义了不同级别的操作,它们之间存在层次关系。例如,随机访问迭代器同时具有双向迭代器、前向迭代器、输入迭代器和输出迭代器的功能。理解这些迭代器类型及其用途有助于编写高效、灵活的 C++ 代码。

Iterator的基本操作(Basic Operations of Iterators)

迭代器的基本操作包括移动迭代器、访问元素、迭代器之间的比较以及迭代器算术运算。以下是这些操作的详细解释:

a. 移动迭代器(Moving Iterators): 移动迭代器是指改变迭代器所指向的容器元素。不同类型的迭代器提供了不同的移动操作:

  • 输入迭代器和输出迭代器:仅支持自增操作(++),从前向后移动;
  • 前向迭代器:支持自增操作(++),从前向后移动;
  • 双向迭代器:支持自增操作(++)和自减操作(–),可以在前后两个方向上移动;
  • 随机访问迭代器:支持自增操作(++)、自减操作(–)以及其他算术运算,可以直接访问任意元素。

b. 访问元素(Accessing Elements): 迭代器可以通过解引用操作( *)访问其指向的元素。输入迭代器、前向迭代器、双向迭代器和随机访问迭代器都支持读取元素值,而输出迭代器和前向迭代器支持修改元素值。

c. 迭代器之间的比较(Comparison between Iterators): 迭代器之间可以进行相等(==)和不相等(!=)比较。对于随机访问迭代器,还可以进行大于(>)、小于(<)、大于等于(>=)和小于等于(<=)的比较。这些比较操作在遍历容器和判断迭代器位置时非常有用。

d. 迭代器算术运算(Iterator Arithmetic Operations): 迭代器算术运算主要针对随机访问迭代器,支持以下操作:

  • 加法(+)和减法(-):可以通过加减整数值来改变迭代器的位置,如 iter + 5 或 iter - 3;
  • 加等(+=)和减等(-=):可以实现原地加减整数值的效果,如 iter += 5 或 iter -= 3;
  • 求距离(-):计算两个迭代器之间的元素个数,如 iter2 - iter1。

实例讲解(Examples and Explanations)

a. 示例1:使用输入迭代器读取数据(Example 1: Reading Data with Input Iterators)

以下是一个使用输入迭代器从 vector 容器中读取数据的示例:

#include <iostream>
#include <vector>int main() {// 初始化一个 vector 容器std::vector<int> vec = {1, 2, 3, 4, 5};// 使用输入迭代器读取 vector 中的数据for (std::vector<int>::const_iterator iter = vec.begin(); iter != vec.end(); ++iter) {// 使用解引用操作访问当前元素的值int value = *iter;std::cout << value << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们首先初始化了一个包含五个整数的 vector 容器。然后,我们使用一个输入迭代器 iter 来遍历容器中的所有元素。注意,这里我们使用了 const_iterator 类型的迭代器,因为我们只需要读取容器中的数据,不需要修改它。

遍历过程中,我们使用 vec.begin() 函数获取容器的起始迭代器,并通过 iter != vec.end() 判断是否已经到达容器的末尾。在循环体内,我们使用解引用操作 *iter 访问当前元素的值,并将其输出。最后,我们使用自增操作 ++iter 将迭代器向后移动一位,继续访问下一个元素。

b. 示例2:使用输出迭代器输出数据(Example 2: Writing Data with Output Iterators)

以下是一个使用输出迭代器将数据写入 vector 容器的示例:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>int main() {// 初始化一个 vector 容器std::vector<int> vec = {1, 2, 3, 4, 5};// 创建一个空的 vector 容器,用于存储乘以 2 后的数据std::vector<int> output_vec;// 使用输出迭代器将数据写入 output_vecstd::transform(vec.begin(), vec.end(), std::back_inserter(output_vec), [](int value) {return value * 2;});// 输出 output_vec 中的数据for (int value : output_vec) {std::cout << value << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们首先初始化了一个包含五个整数的 vector 容器 vec。接着,我们创建了一个空的 vector 容器 output_vec,用于存储将 vec 中的每个元素乘以 2 后的数据。

我们使用 std::transform 算法来实现这个操作。std::transform 接受输入容器的起始和结束迭代器(在这里是 vec.begin()vec.end()),一个输出迭代器(在这里是 std::back_inserter(output_vec)),以及一个用于转换数据的函数对象(在这里是一个 lambda 表达式 [](int value) { return value * 2; })。

std::back_inserter 是一种特殊的输出迭代器,它可以将数据插入到容器的末尾。在这个示例中,我们使用 std::back_inserter 将经过转换的数据依次插入到 output_vec 中。

最后,我们遍历 output_vec 并输出其中的数据。

c. 示例3:前向迭代器的应用场景(Example 3: Application Scenarios of Forward Iterators)

以下是一个使用前向迭代器遍历和修改 list 容器中的数据的示例:

#include <iostream>
#include <list>
#include <algorithm>int main() {// 初始化一个 list 容器std::list<int> lst = {1, 2, 3, 4, 5};// 使用前向迭代器遍历和修改 list 中的数据for (std::list<int>::iterator iter = lst.begin(); iter != lst.end(); ++iter) {// 使用解引用操作访问并修改当前元素的值*iter *= 2;}// 输出修改后的 list 中的数据for (int value : lst) {std::cout << value << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们首先初始化了一个包含五个整数的 list 容器。然后,我们使用一个前向迭代器 iter 来遍历容器中的所有元素。

遍历过程中,我们使用 lst.begin() 函数获取容器的起始迭代器,并通过 iter != lst.end() 判断是否已经到达容器的末尾。在循环体内,我们使用解引用操作 *iter 访问并修改当前元素的值,将其乘以 2。最后,我们使用自增操作 ++iter 将迭代器向后移动一位,继续访问下一个元素。

这个示例展示了前向迭代器的一个典型应用场景,即遍历并修改容器中的数据。前向迭代器既可以用于读取数据,也可以用于写入数据,因此在需要同时读写数据的场景中非常有用。

d. 示例4:双向迭代器与随机访问迭代器的比较与应用(Example 4: Comparison and Application of Bidirectional Iterators and Random Access Iterators)

以下示例比较了双向迭代器和随机访问迭代器的用法,并展示了它们在不同容器中的应用场景。

#include <iostream>
#include <vector>
#include <list>int main() {// 初始化一个 vector 容器std::vector<int> vec = {1, 2, 3, 4, 5};// 使用随机访问迭代器遍历 vector,从后向前输出元素for (std::vector<int>::reverse_iterator riter = vec.rbegin(); riter != vec.rend(); ++riter) {std::cout << *riter << " ";}std::cout << std::endl;// 初始化一个 list 容器std::list<int> lst = {1, 2, 3, 4, 5};// 使用双向迭代器遍历 list,从后向前输出元素for (std::list<int>::reverse_iterator riter = lst.rbegin(); riter != lst.rend(); ++riter) {std::cout << *riter << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们首先初始化了一个包含五个整数的 vector 容器和一个 list 容器。接着,我们分别使用随机访问迭代器和双向迭代器遍历这两个容器,并从后向前输出它们的元素。

对于 vector 容器,我们使用 std::vector<int>::reverse_iterator 类型的随机访问迭代器。我们从容器的末尾开始遍历,使用 vec.rbegin() 获取反向起始迭代器,判断迭代器是否到达容器的反向末尾(riter != vec.rend()),并使用自增操作 ++riter 将迭代器向前移动。

对于 list 容器,我们使用 std::list<int>::reverse_iterator 类型的双向迭代器。遍历过程与 vector 容器类似,但需要注意的是,由于 list 容器不支持随机访问,因此我们不能直接使用整数索引访问元素。

这个示例展示了双向迭代器和随机访问迭代器在不同容器中的应用,并且通过使用反向迭代器演示了如何从后向前遍历容器。

三、C++ Iterator模板库在容器中的应用(Application of C++ Iterator Template Library in Containers)

C++ Iterator模板库在各种顺序容器中的应用非常广泛,这些容器包括 vector、list、deque 和 array。迭代器为我们提供了一种通用的访问和操作容器元素的方法。

顺序容器(Sequential Containers)

a. vector: vector 是一种动态数组,它支持随机访问,插入和删除元素的时间复杂度随着距离容器尾部的距离而变化。vector 的迭代器属于随机访问迭代器,提供了丰富的功能,包括访问、修改、移动和比较迭代器等。在 vector 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。

b. list: list 是一种双向链表,支持在常数时间内在任意位置插入和删除元素。list 的迭代器属于双向迭代器,可以在前后两个方向上移动,支持访问、修改和比较迭代器。在 list 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。

c. deque: deque 是一种双端队列,支持在两端进行快速插入和删除操作,同时也支持随机访问。deque 的迭代器属于随机访问迭代器,提供了丰富的功能,包括访问、修改、移动和比较迭代器等。在 deque 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。

d. array: array 是一种静态数组,大小在编译时确定,因此不支持动态改变大小。array 的迭代器属于随机访问迭代器,提供了丰富的功能,包括访问、修改、移动和比较迭代器等。在 array 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。

关联容器(Associative Containers)

关联容器(Associative Containers)是一种支持基于键的高效查找、访问和删除操作的容器。这些容器在内部通常采用平衡二叉树(例如红黑树)或哈希表等数据结构实现。关联容器的迭代器通常属于双向迭代器,允许在前后两个方向上移动。

a. set: set 是一种基于键的有序集合,其中每个键唯一且不能修改。set 内部的元素会按照键的顺序进行排序。在 set 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。另外,set 容器还提供了一些查找和删除元素的成员函数,如 find()count()erase()

b. multiset: multiset 与 set 类似,但允许存储多个相同的键。multiset 内部的元素同样会按照键的顺序进行排序。在 multiset 容器中,可以使用与 set 相同的成员函数获取迭代器,以及进行查找和删除操作。

c. map: map 是一种基于键值对的有序关联容器,其中每个键唯一且不能修改,每个键对应一个值。map 内部的元素会按照键的顺序进行排序。在 map 容器中,可以使用 begin()end()rbegin()rend() 等成员函数获取不同位置的迭代器。map 容器还提供了一些查找和删除元素的成员函数,如 find()count()erase()

d. multimap: multimap 与 map 类似,但允许存储多个具有相同键的键值对。multimap 内部的元素同样会按照键的顺序进行排序。在 multimap 容器中,可以使用与 map 相同的成员函数获取迭代器,以及进行查找和删除操作。

无序容器(Unordered Containers)

无序容器(Unordered Containers)是一种基于哈希表实现的容器,它们提供了快速的查找、插入和删除操作,但内部元素并不保证有序。无序容器的迭代器通常属于前向迭代器,可以在前向方向上移动。

a. unordered_set: unordered_set 是一种基于键的无序集合,其中每个键唯一且不能修改。在 unordered_set 容器中,可以使用 begin()end() 等成员函数获取不同位置的迭代器。另外,unordered_set 容器还提供了一些查找和删除元素的成员函数,如 find()count()erase()

b. unordered_multiset: unordered_multiset 与 unordered_set 类似,但允许存储多个相同的键。在 unordered_multiset 容器中,可以使用与 unordered_set 相同的成员函数获取迭代器,以及进行查找和删除操作。

c. unordered_map: unordered_map 是一种基于键值对的无序关联容器,其中每个键唯一且不能修改,每个键对应一个值。在 unordered_map 容器中,可以使用 begin()end() 等成员函数获取不同位置的迭代器。unordered_map 容器还提供了一些查找和删除元素的成员函数,如 find()count()erase()

d. unordered_multimap: unordered_multimap 与 unordered_map 类似,但允许存储多个具有相同键的键值对。在 unordered_multimap 容器中,可以使用与 unordered_map 相同的成员函数获取迭代器,以及进行查找和删除操作。

四、C++ Iterator模板库的最佳实践与注意事项(Best Practices and Precautions for C++ Iterator Template Library)

在使用 C++ Iterator 模板库时,了解一些最佳实践和注意事项有助于编写高效且稳定的代码。

迭代器失效的问题(Iterator Invalidating Issues)

在使用迭代器时,需要注意迭代器失效的问题。当对容器进行插入、删除等操作时,某些迭代器可能会失效。失效的迭代器可能会导致未定义的行为,因此在使用迭代器时要确保它们始终有效。例如,在遍历容器的过程中避免对容器进行插入或删除操作,或者使用支持插入和删除操作的容器,如 list。

迭代器适配器的使用(Using Iterator Adapters)

迭代器适配器是一种特殊的迭代器,它们可以对其他迭代器进行封装并提供额外的功能。C++ 标准库提供了一些常用的迭代器适配器,例如反向迭代器(reverse_iterator)、插入迭代器(insert_iterator)、流迭代器(istream_iterator 和 ostream_iterator)等。了解并合理使用这些迭代器适配器可以简化代码并提高效率。

注意事项与常见错误(Precautions and Common Mistakes)

  • 避免越界访问:在使用迭代器进行访问和操作时,确保迭代器始终在容器的有效范围内,以避免越界访问。
  • 使用正确的迭代器类型:根据容器的特性选择合适的迭代器类型,例如对于 list 容器,选择双向迭代器,而不是随机访问迭代器。
  • 注意 const 迭代器:在访问 const 容器时,需要使用 const_iterator,以保证容器的内容不会被意外修改。
  • 在遍历过程中修改容器:遍历容器时,要注意不要直接修改容器的大小(如插入和删除元素),因为这可能导致迭代器失效。如果需要修改容器,可以先将待修改的元素保存起来,然后在遍历结束后进行修改。

五、总结(Conclusion)

C++ Iterator模板库的重要性(Importance of C++ Iterator Template Library)

C++ Iterator 模板库在 C++ 标准库中扮演了至关重要的角色。迭代器为我们提供了一种通用的访问和操作容器元素的方法,无论底层数据结构如何实现。迭代器的存在使得 C++ 标准库中的各种容器具有更高的可扩展性和灵活性,同时也简化了程序员在处理不同类型容器时的工作。掌握迭代器的用法是成为一名高效的 C++ 程序员的关键。

学习与成长(Learning and Growth)

学习 C++ Iterator 模板库不仅能帮助您提高编程技能,还能增进对 C++ 语言和标准库的理解。在实际编程过程中,不断地尝试和实践各种迭代器类型和操作将使您更加熟练地应用它们。此外,关注迭代器的最佳实践和注意事项可以帮助您避免常见的错误,提高代码质量和稳定性。

总之,掌握 C++ Iterator 模板库对于任何 C++ 程序员来说都是非常重要的。通过不断学习和实践,您将能够更有效地使用 C++ 迭代器,编写出更加高效和稳定的代码。

相关文章:

C++ 迭代器之旅(Journey of Iterators)

C 迭代器之旅&#xff08;Journey of Iterators&#xff09; 一、引言&#xff08;Introduction&#xff09;C Iterator模板库简介&#xff08;Overview of C Iterator Template Library&#xff09;Iterator的重要性和作用&#xff08;The Importance and Role of Iterators&a…...

使用全球融合CDN的10大优势

根据预估&#xff0c;今年的全球内容交付网络&#xff08;CDN&#xff09;市场预计将达到424亿美元。而由于移动应用程序的激增和人工智能尤其是ChatGPT等相关领域的快速发展将进一步带来CDN市场的快速增长&#xff0c;可以说全球CDN的黄金时代才刚开始。 融合CDN和多CDN战略是…...

前端学习:HTML图像、表格、列表

目录 图像 一、图像标签和源属性(Src) 二、替换文本属性(Alt) 三、设置图片样式基本属性 四、图像标签 表格 一、标签 补充: 二、表格的表头 三、表格常用标签和属性 标签 属性 列表 一、无序列表 二、有序列表 三、定义列表 四、列表常用标签属性 图像 一、…...

202305读书笔记|《因思念而沉着》——任何赞美都是身外之物唯自由可随身携带

《因思念而沉着》作者巴哑哑&#xff0c;忘了是什么时候加入的书架&#xff0c;昨天下班地铁上读完的书。是美的&#xff01; 部分节选如下&#xff1a; 羽叶茑萝举着熄灭的花青色的小枣落了一地所以哭泣沾染上了你的脸 在没落下 当我们开始生活 就是开始患上了眼疾你独自悲伤…...

M1 M2上能安装上Autocad 2024 Mac 中文版吗 autocad m1 m2版本有啦 终于支持Ventura 13x了

AutoCAD是一款强大的工具&#xff0c;适合于各种领域的设计和绘图。它具有二维图形和三维建模功能、多种文件格式支持、自定义命令和样式、批处理和脚本等特点&#xff0c;可以帮助用户实现高质量的设计和建模。同时&#xff0c;还支持云端存储和共享&#xff0c;方便用户随时随…...

【题解】P4055 [JSOI2009] 游戏

link 题目大意 题目说得比较清楚。 题解 前置知识&#xff1a;二分图最大匹配、基础博弈论。 每个点只能走一次的四联通点阵&#xff0c;可以想到二分图匹配。 将其套路地奇偶分点&#xff0c;相邻两点连边&#xff08;显然不能为 #&#xff09;。 先求一个最大匹配。 …...

P1020 [NOIP1999 普及组] 导弹拦截

题目描述 某国为了防御敌国的导弹袭击&#xff0c;发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。某天&#xff0c;雷达捕捉到敌国的导弹来袭。由于该系统…...

Makefile学习

什么是Makefile 使用 GCC 编译器在 Linux 进行 C 语言编译&#xff0c;通过在终端执行 gcc 命 令来完成 C 文件的编译&#xff0c;如果我们的工程只有一两个 C 文件还好&#xff0c;需要输入的命令不多&#xff0c;当文件有几十、上百甚至上万个的时候用终端输入 GCC 命令的方…...

2.4 随机变量函数的分布

学习目标&#xff1a; 学习随机变量函数的分布&#xff0c;我会采取以下步骤&#xff1a; 熟悉随机变量的基本概念和分布&#xff1a;在学习随机变量函数的分布之前&#xff0c;需要先掌握随机变量的基本概念和分布&#xff0c;包括离散型随机变量和连续性随机变量的概率密度…...

数据结构【一】:前缀表达式与后缀表达式的区别

在早期计息机系统中&#xff0c;由于没有括号规定运算顺序&#xff0c;因此&#xff0c;依靠出栈和入栈两种方式&#xff0c;限定元素和符号之间的关系确定了前缀表达式和后缀表达式两种运算方式&#xff0c;中缀表达式即为普通的运算表达式&#xff1b;注意&#xff0c;在栈结…...

搭建 PostgreSQL

端口&#xff1a;5432 代理备份端口&#xff1a;6432 下载 postgresql-15.0-1-windows-x64 乱码显示 配置环境变量 PGDATA数据目录位置 找到postgresql.conf文件&#xff0c; 修改参数 lc_messagesUTF8 max_connections 1000 shared_buffers4GB work_mem8MB 问题&#xff1a…...

Nmap入门到高级【第四章】

预计更新Nmap基础知识 1.1 Nmap简介和历史 1.2 Nmap安装和使用方法 1.3 Nmap扫描技术和扫描选项 Nmap扫描技术 2.1 端口扫描技术 2.2 操作系统检测技术 2.3 服务和应用程序检测技术 2.4 漏洞检测技术 Nmap扫描选项 3.1 扫描类型选项 3.2 过滤器选项 3.3 探测选项 3.4 输出选项…...

c++正则表达式及其使用,超级详细

文章目录 概述正则表达式语法正则表达式操作std::regex_matchstd::regex_replacestd::regex_search 实例匹配邮箱替换 HTML 标签搜索 URL 总结 概述 正则表达式是一种用于匹配字符串的工具&#xff0c;可以在文本中查找特定的模式&#xff0c;并且可以快速地对字符串进行搜索和…...

【LeetCode: 剑指 Offer II 099. 最小路径之和 | 暴力递归 | DFS =>记忆化搜索=>动态规划】

&#x1f34e;作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域新星创作者&#x1f3c6;&#xff0c;保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享&#x1f48e;&#x1f48e;&#x1f48e; &#x1f34e;座右…...

Python OpenCV 计算机视觉:6~7

原文&#xff1a;OpenCV Computer Vision with Python 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&#xff0c;你最…...

LabView中数组的使用2-1

在LabView中&#xff0c;数组用来管理相同类型的数据。 1 在前面板中创建数组 1.1 创建空数组 在前面板中创建数组时&#xff0c;首先在前面板中点击鼠标右键&#xff0c;弹出“控件”对话框&#xff0c;之后选择“新式->数组、矩阵与簇->数组”&#xff0c;在前面板中…...

Android 10.0 系统systemui下拉通知栏的通知布局相关源码分析

1.前言 在android10.0的系统rom开发中,在进行systemui中的下拉通知栏的布局自定义的时候,对于原生systemui的 系统的下拉通知栏的通知布局的了解也是非常重要的,接下来就来分析下相关的下拉通知栏的通知布局的相关 源码流程,了解这些才方便对通知栏的布局做修改 2.系统…...

研读Rust圣经解析——Rust learn-3(变量与可变性,数据类型)

研读Rust圣经解析——Rust learn-3&#xff08;变量与可变性&#xff0c;数据类型&#xff09; 变量|常量与可变性变量声明案例为什么不可变变量可变&#xff08;mut关键字&#xff09;变量可变&#xff08;覆盖&#xff09; 常量声明 数据类型标量类型整型整型字面值整型溢出问…...

接口的多继承多实现

接口的多继承多实现 目录 接口的多继承多实现多继承&#xff08;接口1 extends 接口2,接口3&#xff09;多实现&#xff08;实现类 实现 接口1&#xff0c;接口2&#xff09;总结1.类与类的关系2.类和接口的关系3.接口与接口的关系 多继承&#xff08;接口1 extends 接口2,接口…...

腾讯-iOS面试题-答案

一面 1、介绍一下实习的项目&#xff0c;任务分工,做了哪些工作&#xff1f;介绍实习内容 2、网络相关的&#xff1a;项目里面使用到什么网络库&#xff0c;用过ASIHTTP库吗 在iOS开发中&#xff0c;常用的网络库包括&#xff1a; URLSession&#xff1a;苹果官方提供的网络…...

SQL Server内存架构

2. 内存架构 所谓内存架构,这里是指SQL Server实例内存管理、使用与相关逻辑设计及实现等方面内容。更具体一点,就是讲SQL Server实例分配、管理和使用其内存空间的内部机制。本书1.1节中我们已经讲过,SQL Server实例包括多个内部机制各不相同的内存区域,在此,我们将讲解…...

有哪些功能强大,但是很小众的Python库呢?

Python生态系统中有很多小众但非常强大的库&#xff0c;一般&#xff0c;通俗的规律就是&#xff0c;越是高端&#xff0c;越小众&#xff0c;但是&#xff0c;高端不代表难学&#xff0c;只要理论到了&#xff0c;用起来照样嗖嗖的&#xff0c;以下是一些参考的高端小众库&…...

SpringBoot设计了哪些可拓展的机制?

SpringBoot核心源码 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { ...this.primarySources new LinkedHashSet(Arrays.asList(primarySources));// Servletthis.webApplicationType WebApplicationType.deduceFromClass…...

Layer组件多个iframe弹出层打开与关闭及参数传递

Layer官网地址&#xff1a;http://layer.layui.com/ 1、多个iframe弹出层&#xff08;非嵌套&#xff09; 1.打开iframe弹出层js代码 &#xff08;1&#xff09;示例一&#xff1a; content参数可传入要打开的页面&#xff0c;type参数传2&#xff0c;即可打开iframe类型的弹层…...

BearPi环境搭建及基本使用

这是一篇总结&#xff0c;一些坑的记录 具体教程请访问&#xff1a; BearPi-HM_Nano: 小熊派BearPi-HM Nano开发板基于HarmonyOS的源码 - Gitee.com 第一步&#xff1a;安装虚拟机 不做赘述 第二步&#xff1a;下载资源 这里要用到ubuntu的一些基础知识&#xff0c;不会的…...

算法笔记-换根DP

换根DP 一般是给定一棵不定根树&#xff0c;求以每个节点为根的一些信息。可以通过二次扫描&#xff1a; 第一次扫描&#xff0c;任选一点为根&#xff0c;在有根树上&#xff0c;自底向上转移第二次扫描&#xff0c;从上一次扫描的根开始&#xff0c;自顶向下计算 P3478 [P…...

LeetCode 785. Is Graph Bipartite【DFS,二分图】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

【微信小程序】-- 分包 - 独立分包 分包预下载(四十五)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…...

2.3 连续性随机变量

思维导图&#xff1a; 学习目标&#xff1a; 我会按照以下步骤学习连续型随机变量&#xff1a; 复习概率论的基础知识&#xff0c;包括概率、期望、方差等概念和公式&#xff0c;以及离散型随机变量的概率分布函数和概率质量函数的概念和性质。 学习连续型随机变量的概念和性…...

【DES详解】(一)处理input block(64 bits)

一、DES 加密算法总览 0-1、初识置换 IP&#xff08;Initial Permutation&#xff09; 输入&#xff1a;明文&#xff08;64 bits&#xff09; 过程&#xff1a;初识置换 输出&#xff1a;处理后的明文permuted input&#xff08;64 bits&#xff09; 首先&#xff0c;对需要解…...