【C++】map和set详解

news2024/11/27 14:49:15

目录

 1. 关联式容器

2. 键值对pair

3. 树形结构的关联式容器

4. set

4.1 set的介绍

4.2 set的构造

4.3 set的迭代器

4.4 set的容量

4.5 set的常用函数

5. multiset

6. map

6.1 map的介绍

6.2 map的构造

6.3 map的迭代器

6.4 map的容量

6.5 map的operator[]

6.6 map的常用函数

7. multimap


 

1. 关联式容器

在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、 forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?

关联式容器(associative containers)与序列式容器(sequential containers)是C++标准库中的两种不同类型的容器。

序列式容器是一种按照元素在容器中的位置进行存储和访问的容器。它们按照元素的插入顺序进行存储,并且支持顺序访问元素的特性。常见的序列式容器有:vector、deque、list和forward_list。

关联式容器是一种按照键值(key)进行存储和访问的容器。它们通过一对键值对(key-value pair)来存储元素,其中的键(key)用于唯一标识元素,并且支持根据键值进行快速检索的特性。常见的关联式容器有:set、multiset、map和multimap。

2. 键值对pair

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然 有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。

SGI-STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;    //key
	T2 second;    //value

    //构造函数
	pair() : first(T1()), second(T2())
	{}
	pair(const T1& a, const T2& b) : first(a), second(b)
	{}
};

所以,C++ 中的键值对是通过 pair 类来表示的。

pair包含两个成员变量first和second,分别表示两个值的类型T1和T2。我们可以使用pair来创建键值对或者存储两个值。

int main() 
{
    // 创建一个键值对
    pair<int, string> student(1, "Alice");

    // 访问键值对的值
    cout << student.first << ": " << student.second << endl;

    // 修改键值对的值
    student.first = 2;
    student.second = "Bob";

    // 创建临时键值对
    pair<int, string> temp(3, "Charlie");

    // 使用make_pair创建临时键值对
    auto temp2 = make_pair(4, "David");

    return 0;
}

pair可以用于存储键值对,也可以用于其他需要存储两个不同类型的值的场景。它在C++标准库中被广泛使用,例如在map、unordered_map等容器中存储键值对。

此外,库中还设计了一个函数模板 make_pair, 可以根据传入的参数,去调用 pair 构建对象并返回。

template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& t1, T2&& t2);

make_pair接受两个参数t1和t2,并将它们打包为一个pair对象并返回。make_pair会自动推导出pair对象中的第一个值和第二个值的类型。

以下是使用make_pair创建pair对象的示例:

int main() 
{
    // 创建pair对象
    auto p1 = make_pair(1, "Alice");

    // 创建pair对象并指定类型
    pair<int, string> p2 = make_pair(2, "Bob");

    // 输出pair对象的值
    cout << p1.first << ": " << p1.second << endl;
    cout << p2.first << ": " << p2.second << endl;

    return 0;
}

make_pair可以方便地创建pair对象,无需显式指定类型,编译器会根据参数类型进行类型推导。它常用于在容器中插入键值对或者返回键值对的函数中。

3. 树形结构的关联式容器

根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结 构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。下面一依次介绍每一 个容器。

4. set

4.1 set的介绍

set容器:它是一个关联容器,用于存储唯一的元素,且按照一定的顺序排列。set容器中的元素按照默认的排序顺序存储,或者可以通过自定义的排序函数进行排序。set容器实际上是一个红黑树(red-black tree)实现的。

set容器中的元素会自动按照键的顺序进行排序,保持元素的有序性。同时,set容器中的元素是唯一的,即相同的元素只能出现一次

4.2 set的构造

set容器可以使用多种方式进行构造,以下是常见的构造方式:

1. 默认构造函数:

set<int> mySet; // 创建一个空的set容器

2. 使用迭代器构造:

vector<int> vec = {1, 2, 3, 4, 5};
set<int> mySet(vec.begin(), vec.end()); // 使用vec容器中的元素构造set容器

3. 使用初始化列表构造:

set<int> mySet = {1, 2, 3, 4, 5}; // 使用初始化列表中的元素构造set容器

4. 拷贝构造函数:

set<int> mySet1 = {1, 2, 3, 4, 5};
set<int> mySet2(mySet1); // 使用另一个set容器的副本构造新的set容器

需要注意的是,set容器中的元素默认按照升序进行排序。如果希望使用自定义的排序规则,可以在构造过程中提供一个比较函数对象作为参数,或者通过重载元素类型的比较运算符来实现。

例如,如果要创建一个按照降序排序的set容器,可以使用以下方式构造:

struct Compare 
{
    bool operator()(int a, int b) const 
    {
        return a > b;
    }
};

set<int, Compare> mySet; // 使用自定义的比较函数对象构造set容器

4.3 set的迭代器

set容器提供了两种类型的迭代器:正向迭代器和反向迭代器。

正向迭代器:

  • begin():返回指向set容器中第一个元素的迭代器。
  • end():返回指向set容器中最后一个元素之后位置的迭代器。
int main()
{
	set<int> s1 = { 1, 4, 2, 3, 5 };

	set<int>::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	return 0;
}

 

 反向迭代器:

  • rbegin():返回指向set容器中最后一个元素的迭代器。
  • rend():返回指向set容器中第一个元素之前位置的迭代器。
int main()
{
	set<int> s1 = { 1, 4, 2, 3, 5 };


	set<int>::reverse_iterator rit = s1.rbegin();

	while (rit != s1.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	return 0;
}

4.4 set的容量

set容器提供了以下几个容量函数来获取容器的大小和容量信息:

  1. size():返回set容器中元素的个数。
  2. empty():判断set容器是否为空,如果为空返回true,否则返回false。
  3. max_size():返回set容器能够容纳的最大元素个数,这个值取决于系统或者编译器的限制。
int main() 
{
    set<int> mySet = { 1, 4, 2, 3, 5 };

    // 使用size()函数获取set的大小
    cout << "Set的大小:" << mySet.size() << endl;

    // 使用empty()函数判断set是否为空
    if (mySet.empty()) 
    {
        cout << "Set为空" << endl;
    }
    else 
    {
        cout << "Set不为空" << endl;
    }

    // 使用max_size()函数获取set的最大容量
    cout << "Set的最大容量:" << mySet.max_size() << endl;

    return 0;
}

4.5 set的常用函数

set容器提供了一些常用的函数来进行元素的插入、删除、查找等操作。下面是set容器的一些常用函数:

  1. 插入元素:

    insert(val):将元素val插入到set容器中。

    insert(first, last):将区间[first, last)内的元素插入到set容器中。 

  2. 删除元素:

    erase(val):删除set容器中与val相等的元素。

    erase(iterator):删除指定迭代器指向的元素。

    erase(first, last):删除区间[first, last)内的元素。

    clear():清空set容器中的所有元素。 

  3. 查找元素:

    find(val):在set容器中查找与val相等的第一个元素,如果找到返回指向该元素的迭代器,否则返回end()迭代器。

    count(val):返回set容器中与val相等的元素的个数,由于set容器中元素的唯一性,所以返回值只能是0或1。

    lower_bound(val):返回一个迭代器,指向set容器中第一个不小于val的元素,如果不存在这样的元素,则返回set容器的end()迭代器。

    upper_bound(val):返回一个迭代器,指向set容器中第一个大于val的元素,如果不存在这样的元素,则返回set容器的end()迭代器。

    equal_range(val):返回一个pair对象,包含一个迭代器范围,表示与val相等的元素在set容器中的位置。如果不存在这样的元素,则返回一个pair对象,两个迭代器都指向set容器的end()位置。

需要注意的是,set容器中的元素是按照一定的排序方式进行存储的,默认情况下是按照升序排列。另外,由于set容器中元素的唯一性,所以插入重复的元素时,只会插入一个。

int main() 
{
    set<int> mySet;

    // 插入元素到set
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(30);

    // 查找元素
    set<int>::iterator it = mySet.find(20);
    if (it != mySet.end()) 
    {
        cout << "元素存在" << endl;
    }
    else 
    {
        cout << "元素不存在" << endl;
    }

    // 删除元素
    mySet.erase(20);

    // 获取set的大小
    cout << "set的大小为:" << mySet.size() << endl;

    // 清空set
    mySet.clear();

    // 判断set是否为空
    if (mySet.empty()) 
    {
        cout << "set为空" << endl;
    }
    else 
    {
        cout << "set不为空" << endl;
    }

    return 0;
}

5. multiset

multiset是C++ STL中的容器,它是一个有序的集合,可以存储多个相同的元素。

此外,multiset 查找冗余的数据时,返回的是中序遍历中,第一次出现的元素 。

multiset的特点包括:

  • 元素的插入是有序的,插入操作会将元素按照一定的顺序插入到容器中。
  • 允许存储重复的元素,即可以插入相同的元素多次。
  • multiset中的元素是自动排序的,默认按照元素的升序进行排序,也可以通过指定比较函数来按照其他方式进行排序。
  • 支持快速的插入和删除操作,时间复杂度为O(logN)。
int main() 
{
    multiset<int> numbers;

    // 向multiset中插入元素
    numbers.insert(1);
    numbers.insert(3);
    numbers.insert(2);
    numbers.insert(2);

    cout << "multiset中的元素:" << endl;
    for (auto it = numbers.begin(); it != numbers.end(); ++it) 
    {
        cout << *it << " ";
    }
    cout << endl;

    // 查找multiset中的元素
    auto it = numbers.find(2);
    if (it != numbers.end()) 
    {
        cout << "找到元素2" << endl;
    }
    else 
    {
        cout << "未找到元素2" << endl;
    }

    // 删除multiset中的元素
    numbers.erase(2);

    cout << "删除元素2后的multiset:" << endl;
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

6. map

6.1 map的介绍

map容器:它是一个关联容器,用于存储键值对(key-value pairs)。其中的每个元素都由一个键(key)和一个值(value)组成。map容器中的元素按照键的顺序进行排序,并且每个键只能在map中出现一次。因此可以通过键快速查找和访问对应的值。map容器实际上是一个红黑树(red-black tree)实现的。

map的特点包括:

  1. 键唯一性:每个键只能在map中出现一次,如果插入相同键的元素,后面的插入会覆盖前面的。

  2. 按键排序:map中的元素按照键的大小进行排序,默认是按照升序排序。

  3. 二叉搜索树实现:map内部使用红黑树(Red-Black Tree)来实现元素的存储和排序,因此插入、查找和删除等操作的时间复杂度都是O(log n)。

  4. 动态大小:map的大小可以根据需要动态地增加或减小。

key: 键值对中key的类型

T: 键值对中value的类型

Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户 自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的 空间配置器

6.2 map的构造

在C++中,可以使用多种方式构造一个map对象。下面列举几种常用的构造方式:

1. 默认构造函数:创建一个空的map对象。

map<Key, Value> myMap;

2. 初始化列表构造函数:通过初始化列表,创建一个包含多个键值对的map对象。

map<int, string> myMap = { {1, "one"}, {2, "two"}, {3, "three"} };

 3. 使用迭代器构造函数:通过指定起始和结束迭代器,创建一个包含其他容器中元素的map对象

vector<pair<int, string>> vec = { {1, "one"}, {2, "two"}, {3, "three"} };
map<int, string> myMap(vec.begin(), vec.end());

4. 复制构造函数:以另一个map对象作为参数,创建一个与其相同的map对象。

map<int, string> anotherMap(myMap);

5. 移动构造函数:以另一个map对象的右值引用作为参数,创建一个新的map对象,同时将原来的map对象置为空。

map<int, string> newMap(move(myMap));

需要注意的是,在使用map构造函数时,键值对的顺序并不影响map中元素的插入顺序,因为map内部是按照键的排序顺序进行存储和访问的。

此外,使用map的构造函数创建新的map对象时,会根据键的类型进行比较和排序,默认是使用less<Key>来进行比较。如果键的类型没有定义比较函数,则需要通过自定义比较函数或提供自定义的比较类作为额外的模板参数来使用。

6.3 map的迭代器

map提供了两种类型的迭代器:正向迭代器和反向迭代器

正向迭代器:

  • begin():返回指向map中第一个元素的迭代器。
  • end():返回指向map中最后一个元素之后位置的迭代器,相当于尾后迭代器。
int main()
{
	map<int, string> myMap = { {1, "one"}, {2, "two"}, {3, "three"} };

	auto it = myMap.begin();
	while (it != myMap.end())
	{
		cout << it->first << ": " << it->second << endl;
		++it;
	}

	return 0;
}

反向迭代器:

  • rbegin():返回指向map中最后一个元素的迭代器。
  • rend():返回指向map中第一个元素之前位置的迭代器,相当于尾前迭代器。
int main()
{
	map<int, string> myMap = { {1, "one"}, {2, "two"}, {3, "three"} };

	auto rit = myMap.rbegin();
	while (rit != myMap.rend())
	{
		cout << rit->first << ": " << rit->second << endl;
		++rit;
	}

	return 0;
}

另外,C++11引入了范围-based for循环,可以更简洁地遍历map对象。

int main()
{
	map<int, string> myMap = { {1, "one"}, {2, "two"}, {3, "three"} };


	for (const auto& pair : myMap) 
	{
		cout << pair.first << ": " << pair.second << endl;
	}

	return 0;
}

这种写法可以自动推导出迭代器的类型,并且使用引用避免了元素的复制。

6.4 map的容量

获取容量信息:

  • size()函数:返回map中键-值对的数量。
  • empty()函数:如果map为空,则返回true;否则返回false。
int main()
{
	map<int, string> myMap = { {1, "one"}, {2, "two"}, {3, "three"} };

	cout << "Size of map: " << myMap.size() << endl;
	cout << "Is map empty? " << (myMap.empty() ? "Yes" : "No") << endl;

	return 0;
}

6.5 map的operator[]

map的 operator[] 函数用于访问 map 中指定键的值。如果键存在,则返回对应的值;如果键不存在,则会插入一个新的键值对,并返回默认构造的值。

int main() 
{
    map<int, string> map;

    // 插入键值对
    map[1] = "Alice";
    map[2] = "Bob";
    map[3] = "Charlie";

    // 访问指定键的值
    string name1 = map[1];
    cout << "键 1 对应的值是:" << name1 << endl;

    string name4 = map[4];
    cout << "键 4 对应的值是:" << name4 << endl;

    // 修改指定键的值
    map[1] = "Alex";

    // 输出所有键值对
    cout << "所有键值对:" << endl;
    for (const auto& pair : map) 
    {
        cout << "键: " << pair.first << " 值: " << pair.second << endl;
    }

    return 0;
}

 

6.6 map的常用函数

map是C++ STL提供的关联容器,提供了一系列的成员函数来操作和管理map。以下是一些map常用的函数:

  1. 插入元素:

    insert():将键值对插入到map中。

    emplace():在map中就地构造元素。

    emplace_hint():在指定位置之前插入元素。

  2. 访问元素:

    at():返回给定键对应的值,并进行边界检查。

    operator[]:根据键访问对应的值,如果键不存在,则插入对应的键值对。

    find():查找给定键的位置,并返回一个迭代器。

    count():返回给定键在map中出现的次数。

  3. 删除元素:

    erase():删除map中指定的元素或者一个范围内的元素。

    clear():清空map中的所有元素。

int main() 
{
    map<string, int> scores;

    // 添加学生的成绩
    scores["Alice"] = 90;
    scores["Bob"] = 85;
    scores["Charlie"] = 95;
    scores["David"] = 80;

    // 更新学生的成绩
    scores["Alice"] += 5;

    // 查找学生的成绩
    string studentName = "Bob";
    if (scores.find(studentName) != scores.end()) 
    {
        cout << studentName << "的成绩是:" << scores[studentName] << endl;
    }
    else 
    {
        cout << "找不到" << studentName << "的成绩" << endl;
    }

    // 删除学生的成绩
    scores.erase("David");

    // 遍历输出所有学生的成绩
    cout << "所有学生的成绩:" << endl;
    for (const auto& pair : scores) 
    {
        cout << pair.first << "的成绩是:" << pair.second << endl;
    }

    return 0;
}

 

7. multimap

multimap是C++标准库中的一个关联容器,它允许存储一对键-值对,其中键可以重复。multimap内部会根据键的排序规则自动对元素进行排序,并且可以高效地进行插入、删除和查找操作。

map不同,multimap允许多个键相同的元素存在,因此它可以用于存储重复键的场景。multimap的实现基于红黑树,保证了元素的有序性,并提供了一系列函数来操作和访问multimap中的元素。

multimap的特点包括:

  • 元素有序:multimap中的元素按照键的排序规则自动进行排序,可以通过自定义比较函数来指定键的排序规则。
  • 允许重复键:multimap允许存储多个键相同的元素。
  • 动态大小:multimap可以动态地添加或删除元素,它会自动调整内部的存储空间。
  • 高效的插入和删除:multimap内部使用红黑树实现,可以在O(log n)的时间复杂度内进行插入、删除和查找操作。
  • 查找效率高:multimap提供了快速的查找操作,可以在O(log n)的时间复杂度内查找指定键的元素。

由于键可以重复,因此无法使用operator[]函数来直接访问元素,因为这样会产生歧义。

operator[]函数通常用于访问和修改容器中的元素。对于map容器来说,它的每个键只能对应一个值,因此可以使用operator[]通过键直接访问和修改对应的值。但是对于multimap容器,一个键可以对应多个值,如果使用operator[]来访问某个键,那么返回的应该是一个值的集合,而不是单个的值。这就会导致使用operator[]函数的结果不明确。

为了解决这个问题,multimap提供了equal_range函数来查找某个键对应的所有值的范围,然后可以通过迭代器遍历该范围内的所有值。

int main() 
{
    // 创建一个multimap对象
    multimap<int, std::string> scores;

    // 插入元素
    scores.insert(std::make_pair(85, "Alice"));
    scores.insert(std::make_pair(92, "Bob"));
    scores.insert(std::make_pair(77, "Alice"));
    scores.insert(std::make_pair(92, "Charlie"));
    scores.insert(std::make_pair(80, "Alice"));

    // 遍历输出元素
    cout << "Multimap Elements:" << endl;
    for (const auto& score : scores) 
    {
        cout << "Score: " << score.first << ", Student: " << score.second << endl;
    }

    // 查找并输出分数为92的学生
    auto range = scores.equal_range(92);
    if (range.first != scores.end()) 
    {
        cout << "Students with score 92:" << endl;
        for (auto it = range.first; it != range.second; ++it) 
        {
            cout << "Student: " << it->second << endl;
        }
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1903326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】程序设计竞赛

程序设计竞赛 文章目录 程序设计竞赛0x00 基本操作指南0x01 算法分析0x02 STL和基本数据结构栈队列集合map 0x03 排序插入排序归并排序&#xff08;Merge Sort)快速排序 0x04 搜索技术BFSDFS回溯与剪枝 深度迭代ID A*A star双向广搜 0x05 递推方程0x06 高级数据结构并查集二叉树…

STM32快速复习(八)SPI通信

文章目录 前言一、SPI是什么&#xff1f;SPI的硬件电路&#xff1f;SPI发送的时序&#xff1f;二、库函数二、库函数示例代码总结 前言 SPI和IIC通信算是我在大学和面试中用的最多&#xff0c;问的最多的通信协议 IIC问到了&#xff0c;一般SPI也一定会问到。 SPI相对于IIC多了…

HTTP请求响应/与HTTPS区别

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是用于在计算机网络上传输信息的两种协议。 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;: HTTP 是一种用于传输超文本的应用层协议…

Go 依赖注入设计模式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

前后端分离系统

前后端分离是一种现代软件架构模式&#xff0c;特别适用于Web应用开发&#xff0c;它强调将用户界面&#xff08;前端&#xff09;与服务器端应用逻辑&#xff08;后端&#xff09;相分离。两者通过API接口进行数据交互。这种架构模式的主要优势在于提高开发效率、维护性和可扩…

安卓虚拟位置修改

随着安卓系统的不断更新&#xff0c;确保软件和应用与最新系统版本的兼容性变得日益重要。本文档旨在指导用户如何在安卓14/15系统上使用特定的功能。 2. 系统兼容性更新 2.1 支持安卓14/15&#xff1a;更新了对安卓14/15版本的支持&#xff0c;确保了软件的兼容性。 2.2 路…

《算法笔记》总结No.3——排序

基础算法之一&#xff0c;相当重要。在普通的机试中如果没有数据类型和时空限制&#xff0c;基本上选择自己最熟悉的就好。本篇只总结选择排序和插入排序&#xff0c;侧重应用&#xff0c;408中要求的种类更加繁多&#xff0c;此处先不扩展难度~总结最常用的两种排序。 一.选择…

HTML 【实用教程】(2024最新版)

核心思想 —— 语义化 【面试题】如何理解 HTML 语义化 ?仅通过标签便能判断内容的类型&#xff0c;特别是区分标题、段落、图片和表格 增加代码可读性&#xff0c;让人更容易读懂对SEO更加友好&#xff0c;让搜索引擎更容易读懂 html 文件的基本结构 html 文件的文件后缀为 …

VMware虚拟机配置桥接网络

转载&#xff1a;虚拟机桥接网络配置 一、VMware三种网络连接方式 VMware提供了三种网络连接方式&#xff0c;VMnet0, VMnet1, Vmnet8&#xff0c;分别代表桥接&#xff0c;Host-only及NAT模式。在VMware的编辑-虚拟网络编辑器可看到对应三种连接方式的设置&#xff08;如下图…

深度解析Ubuntu版本升级:LTS版本升级指南

深度解析Ubuntu版本升级&#xff1a;Ubuntu版本生命周期及LTS版本升级指南 Ubuntu是全球最受欢迎的Linux发行版之一&#xff0c;其版本升级与维护策略直接影响了无数用户的开发和生产环境。Canonical公司为Ubuntu制定了明确的生命周期和发布节奏&#xff0c;使得社区、企业和开…

viscode-插件

vue组件生成&#xff1a; vue.json {"Print to console": {"prefix": "vue", "body": ["<!-- $1 -->","<template>","<div>","</div>","</template>&q…

全面解析 TypeScript 泛型的二三事

2024年了相信大家都已经在日常开发的过程中使用上了 TypeScript 了。TypeScript 增强了代码可靠性和可维护性&#xff0c;确保减少运行时错误并提高开发人员的工作效率。 TypeScript 通过类型声明 使得 javascript 拥有了强类型校验。而泛型的是类型声明中最重要的一环&#x…

Git在多人开发中的常见用例

前言 作为从一个 svn 转过来的 git 前端开发&#xff0c;在经历过git的各种便捷好处后&#xff0c;想起当时懵懂使用git的胆颤心惊&#xff1a;总是害怕用错指令&#xff0c;又或者遇到报错就慌的场景&#xff0c;想起当时查资料一看git指令这么多&#xff0c;看的头晕眼花&am…

STM32F103C8T6核心板原理图和PCB分享

PCB图 原理图 资料下载地址&#xff1a; 原理图PCB库: https://545c.com/d/45573183-61875742-29897c?p7526 (访问密码: 7526)

Unity【入门】场景切换和游戏退出及准备

1、必备知识点场景切换和游戏退出 文章目录 1、必备知识点场景切换和游戏退出1、场景切换2、鼠标隐藏锁定相关3、随机数和自带委托4、模型资源的导入1、模型由什么构成2、Unity支持的模型格式3、如何指导美术同学导出模型4、学习阶段在哪里获取模型资源 2、小项目准备工作需求分…

小柴带你学AutoSar系列一、基础知识篇(7)术语

目录 缘起 AUTOSAR 专业术语 RH850 专业术语 其他相关术语 flechazohttps://www.zhihu.com/people/jiu_sheng 小柴冲刺嵌入式系统设计师系列总目录https://blog.csdn.net/qianshang52013/article/details/

WordPress网站违法关键词字过滤插件下载text-filter

插件下载地址&#xff1a;https://www.wpadmin.cn/2025.html 插件介绍 WordPress网站违法关键词字过滤插件text-filter由本站原创开发,支持中英文关键字自动替换成**号&#xff0c;可以通过自定义保存修改按钮增加“预设关键字”&#xff0c;也可以导入定义好的txt文本形式的关…

医院挂号系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;患者管理&#xff0c;医生管理&#xff0c;专家信息管理&#xff0c;科室管理&#xff0c;预约信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;专家信息&#xff0…

算法011:最大连续的1的个数

最大连续的1的个数. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/max-consecutive-ones-iii/ 乍一看&#xff0c;这道题很奇怪&#xff0c;什么叫最多翻转k个0&a…

Raylib实现拖拽视口显示

拖拽看左上角数字 #include <raylib.h> // 重整原因&#xff1a;解决新函数放大缩小之下&#xff0c;raylib 的网格采样部分&#xff0c;选择数组的一部分刷新倒缓冲区里 // 从直接建立缓冲区&#xff0c;到先在数组里进行移动&#xff0c;然后再设置检查缓冲区// 最大距…