【STL】pair 与 map:基础、操作与应用

C++ 标准库中提供了许多用于处理数据结构的容器和工具。pair 和 map 是两个非常有用的工具,广泛应用于存储和处理关联数据。在本文中,我们将详细介绍 pair 与 map 的相关操作,并结合代码实例为读者提供清晰的理解。

pair:成对数据的存储

1. pair 基本介绍

pair 是 C++ 标准库中的一种数据结构,它允许我们将两个不同类型的数据组合成一对。它的典型用法是用来返回两个相关联的值,例如姓名和电话号码。每个 pair 包含两个值,这两个值分别可以通过 .first 和 .second 访问。

2. pair 的创建与使用

2.1创建 pair 的几种方式:

直接使用构造函数创建:

pair<string, int> p("Tom", 10086);

使用 make_pair 函数创建:

pair<string, int> p2 = make_pair("make", 191919190);

列表初始化(C++11 新特性):

pair<string, int> p3 = { "hhhh", 19298318 };

2.2pair 的常用操作:

访问 pair 中的第一个和第二个值:

cout << "姓名:" << p.first << endl;
cout << "电话:" << p.second << endl;

判断两个 pair 对象是否相等:

if (p != p2) 
{cout << "不相等" << endl;
}

整体操作如下:

//pair(二元组):成对出现的数据,利用对组可以返回两个数据
#include<iostream>
#include<string>
#include <utility>  // 包含 pair 对组相关的头文件
using namespace std;//pair<第一个值类型, 第二个值类型> pr// 第一个值类型:要储存的第一个值的数据类型
// 第二个值类型:要储存的第二个值的数据类型// 取第一个值:.first
// 取第二个值:.second// 判断相等:==, !=// 测试 pair 的各种构造与操作
void test0()
{// 使用构造函数直接创建 pair 对象,存储姓名和电话pair<string, int> p("Tom", 10086);// 输出 pair 的第一个元素(姓名)和第二个元素(电话)cout << "姓名:" << p.first << endl;cout << "电话:" << p.second << endl;// 使用 make_pair 创建 pair 对象,这是一种常见的方式pair<string, int> p2 = make_pair("make", 191919190);cout << "姓名:" << p2.first << endl;cout << "电话:" << p2.second << endl;// C++11 新特性,使用列表初始化 pair 对象pair<string, int> p3 = { "hhhh",19298318 };cout << "姓名:" << p3.first << endl;cout << "电话:" << p3.second << endl;// 判断两个 pair 对象是否相等,!= 表示不相等if (p != p2){cout << "不相等" << endl;  // 如果 p 和 p2 不相等,输出提示}
}int main()
{test0();  // 调用测试函数return 0;
}

在这里插入图片描述

map:关联式容器

1. map 基本介绍

map 是 C++ 中的一种关联容器,通常用于存储键值对。每个元素都是 pair,其中第一个元素为 键(key),第二个元素为 值(value)。 map 容器的特点是:所有元素会根据 键 的大小自动排序,并且 键值唯一。如果需要允许重复键,可以使用 multimap。

2.map基本操作一览

map<键类型, 值类型, 比较器> mp

  • 键类型:用于存储键的数据类型
  • 值类型:用于存储与键相关联的值的数据类型
  • 比较器:用于键值比较的规则,默认是 less<类型>,即从小到大排序,可以自定义为 greater<类型> 来改变排序顺序

2.1. map构造和赋值:对map容器进行构造和赋值操作

2.1.1 构造:

map<T1, T2> mp;
// map默认构造函数

map(const map& mp);
// 拷贝构造函数

2.1.2 赋值:

map& operator=(const map& mp);
// 重载等号操作符

2.2. map大小和交换:统计map容器的大小并交换两个map容器

size();
// 返回容器中的元素数量

empty();
// 判断容器是否为空

swap(st);
// 交换两个map容器

2.3. map插入和删除:对map容器插入和删除元素

insert(elem);
// 插入一个元素

clear();
// 清空所有元素

erase(pos);
// 删除pos迭代器所指的元素,返回下一个元素的迭代器

erase(beg, end);
// 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。

erase(key);
// 删除键值为 key 的元素

2.4. map查找和统计:查找和统计数据

find(key);
// 查找key是否存在,存在则返回该键的元素的迭代器,不存在则返回map.end()

count(key);
// 统计键值为key的元素个数:
//map 中的键唯一,因此结果要么为 0(不存在),要么为 1(存在)。

2.5. map排序:map容器默认使用键值的升序排序

降序排序使用map<类型,类型,greater<类型>>m;

3. map 构造和赋值

3.1构造:

map 容器提供了几种方式来构造对象,包括默认构造、拷贝构造等。

  • 默认构造: 使用默认构造函数创建一个空的 map 容器。
map<int, int> mp;  // 创建一个空的 map 容器
  • 拷贝构造: 通过拷贝另一个 map 容器来构造新的 map 对象。
map<int, int> mp2(mp);  // 用 mp 初始化 mp2

3.2赋值:

通过重载等号操作符 =,可以将一个 map 容器的内容赋值给另一个 map。

map<int, int> mp3 = mp2;  // 将 mp2 的内容赋值给 mp3

示例:

// 1. map构造和赋值
void test0()
{// 默认构造 map 容器map<int, int> m;// 插入键值对m.insert(pair<int, int>(1, 3));m.insert(pair<int, int>(4, 0));m.insert(pair<int, int>(1, 3));  // 重复键值不会插入m.insert(pair<int, int>(4, 9));  // 键值相同,实值不同,仍然只保留键值唯一的元素m.insert(pair<int, int>(5, 100));print(m);// 拷贝构造map<int, int> m2(m);  // 用 m 初始化 m2print(m2);// 赋值操作map<int, int> m3 = m2;  // 将 m2 的内容赋给 m3print(m3);
}

在这里插入图片描述

4.map的遍历

// 默认排序遍历:
void print(map<int, int>& m)
{// 使用迭代器遍历 map,按升序输出键值对for (map<int, int>::iterator it = m.begin(); it != m.end(); it++){cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";cout << endl;}cout << endl;// auto 简化迭代器类型(C++11)// for (auto it = m.begin(); it != m.end(); it++)// {// 	cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";// 	cout << endl;// }// 基于范围的 for 循环遍历 map (C++11)// for (pair<int,int> mm : m)// {// 	cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";// 	cout << endl;// }// 使用 auto 更简洁// for (auto mm:m)// {// 	cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";// 	cout << endl;// }
}// 降序遍历:使用 greater<int> 进行键值的降序排列
void print1(map<int, int, greater<int>>& m)
{// 通过迭代器遍历 map,按降序输出键值对for (map<int, int, greater<int>>::iterator it = m.begin(); it != m.end(); it++){cout << "键值:" << it->first << " " << "实值:" << it->second << " ";cout << endl;}cout << endl;// 使用 auto 简化代码// for (auto it = m.begin(); it != m.end(); it++)// {// 	cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";// 	cout << endl;// }/*基于范围for循环:注意这里的元素类型为二元组for (pair<int,int> mm : m){cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";cout << endl;}*//*auto最好用,没有之一for (auto mm:m){cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";cout << endl;}*/
}

5. map 大小和交换

5.1获取容器大小:

.size():返回 map 容器中的元素数量。
.empty():判断 map 是否为空。

cout << "Size: " << m.size() << endl;
cout << "Is empty: " << m.empty() << endl;

5.2交换:

.swap():交换两个 map 容器的内容。

map<int, int> m1, m2;
m1[1] = 10; m2[2] = 20;
m1.swap(m2);  // 交换 m1 和 m2 的内容

示例:

// 2. map大小和交换
void test1()
{map<int, int> m;// 插入键值对m.insert(pair<int, int>(1, 3));m.insert(pair<int, int>(2, 0));m.insert(pair<int, int>(5, 3));// 判断 map 是否为空if (m.empty()){cout << "m为空!" << endl;}else{cout << "m的长度为:" << m.size() << endl;}// 交换两个 map 容器map<int, int> m1;m1.insert(pair<int, int>(3, 1));m1.insert(pair<int, int>(4, 1));m1.insert(pair<int, int>(5, 3));cout << "交换前:" << endl;cout << "m: " << endl;print(m);cout << endl << "m1: " << endl;print(m1);// 执行交换m.swap(m1);cout << "交换后:" << endl;cout << "m: " << endl;print(m);cout << endl << "m1: " << endl;print(m1);
}

在这里插入图片描述

6. map 插入和删除

6.1 插入:

  • insert(elem):插入一个键值对元素。
    分为:
.insert(pair<int, int>(first, second)); 
.insert(make_pair(first, second));
.insert(map<int, int>::value_type(first, second));
  • 使用 [] 插入键值对。(好用)
m.insert(pair<int, int>(1, 100));
m[2] = 200;

6.2 删除:

erase(pos):删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end):删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(key):删除键值为 key 的元素。

m.erase(2);          // 删除键值为 2 的元素
m.erase(m.begin());  // 删除第一个元素
m.clear();           // 清空所有元素

示例:

// 3. map插入和删除
void test2()
{map<int, int> m;// 插入键值对的不同方法m.insert(pair<int, int>(1, 1));                // 方法一:pairm.insert(make_pair(2, 100));                  // 方法二:make_pairm.insert(map<int, int>::value_type(3, 44));   // 方法三:value_typem[4] = 55;                                     // 方法四:中括号操作符print(m);// 删除元素m.erase(m.begin());    // 删除迭代器指向的元素print(m);m.erase(3);            // 删除键值为3的元素print(m);m.erase(m.begin(), m.end());   // 删除区间中的所有元素//等价于m.clear();print(m);
}

在这里插入图片描述

7. map 查找和统计

7.1查找:

find(key):查找 key,返回指向该元素的迭代器,如果不存在则返回 map.end()。

auto it = m.find(1);
if (it != m.end()) 
{cout << "查找成功: " << it->first << "实值: " << it->second << endl;
} 
else 
{cout << "查找失败" << endl;
}

7.2统计:

count(key):返回键值为 key 的元素个数,map 中的键唯一,因此结果要么为 0(不存在),要么为 1(存在)

cout << "键值为1的元素数量: " << m.count(1) << endl;

示例:

// 4. map查找和统计
void test3()
{map<int, int> m;m[0] = 45;m[4] = 34;m[5] = 0;// 查找键值为4的元素map<int, int>::iterator it = m.find(4);if (it != m.end()){cout << "查找成功:" << it->first << " " << it->second << endl;}else{cout << "查找失败" << endl;}// 统计键值为0的元素个数if (m.count(0)){cout << "查找成功" << endl << "数量为:" << m.count(0) << endl;}else{cout << "查找失败" << endl;}
}

在这里插入图片描述

8. map 排序

map 默认按照键的升序进行排序。如果需要自定义排序顺序,可以通过第三个模板参数指定比较器(如 greater)。

8.1默认升序排序:

map<int, int> m;
m[3] = 100;
m[1] = 200;
m[2] = 300;

8.2自定义降序排序:

map<int, int, greater<int>> m1;
m1[3] = 100;
m1[1] = 200;
m1[2] = 300;

示例:

// 5. map排序:键值默认从小到大排序
void test4()
{// 默认升序排序map<int, int> m;m[0] = 11;m[1] = 23;m[-22] = 56;print(m);// 使用 greater<int> 进行降序排序map<int, int, greater<int>> m1;m1[0] = 11;m1[1] = 23;m1[-22] = 56;print1(m1);
}

在这里插入图片描述

整体操作如下:

//map:关联式容器// map中所有元素都是pair:
//匿名pair: pair<类型,类型>(键值,实值);//pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
//所有元素都会根据元素的键值自动排序//map不允许容器中有重复key值元素
//multimap允许容器中有重复key值元素#include<iostream>
#include<map>  // 引入 map 关联式容器头文件
using namespace std;// map<键类型, 值类型, 比较器> mp// 键类型:用于存储键的数据类型
// 值类型:用于存储与键相关联的值的数据类型
// 比较器:用于键值比较的规则,默认是 less<类型>,即从小到大排序,可以自定义为 greater<类型> 来改变排序顺序// 1. map构造和赋值:对map容器进行构造和赋值操作
// 构造:
// map<T1, T2> mp;                     // map默认构造函数
// map(const map& mp);                 // 拷贝构造函数// 赋值:
// map& operator=(const map& mp);      // 重载等号操作符// 2. map大小和交换:统计map容器的大小并交换两个map容器
// size();                             // 返回容器中的元素数量
// empty();                            // 判断容器是否为空
// swap(st);                           // 交换两个map容器// 3. map插入和删除:对map容器插入和删除元素
// insert(elem);                       // 插入一个元素
// clear();                            // 清空所有元素
// erase(pos);                         // 删除pos迭代器所指的元素,返回下一个元素的迭代器
// erase(beg, end);                    // 删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
// erase(key);                         // 删除键值为 key 的元素// 4. map查找和统计:查找和统计数据
// find(key);                          // 查找key是否存在,存在则返回该键的元素的迭代器,不存在则返回map.end()
// count(key);                         // 统计键值为key的元素个数// 5. map排序:map容器默认使用键值的升序排序// 默认排序遍历:
void print(map<int, int>& m)
{// 使用迭代器遍历 map,按升序输出键值对for (map<int, int>::iterator it = m.begin(); it != m.end(); it++){cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";cout << endl;}cout << endl;// auto 简化迭代器类型(C++11)// for (auto it = m.begin(); it != m.end(); it++)// {// 	cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";// 	cout << endl;// }// 基于范围的 for 循环遍历 map (C++11)// for (pair<int,int> mm : m)// {// 	cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";// 	cout << endl;// }// 使用 auto 更简洁// for (auto mm:m)// {// 	cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";// 	cout << endl;// }
}// 降序遍历:使用 greater<int> 进行键值的降序排列
void print1(map<int, int, greater<int>>& m)
{// 通过迭代器遍历 map,按降序输出键值对for (map<int, int, greater<int>>::iterator it = m.begin(); it != m.end(); it++){cout << "键值:" << it->first << " " << "实值:" << it->second << " ";cout << endl;}cout << endl;// 使用 auto 简化代码// for (auto it = m.begin(); it != m.end(); it++)// {// 	cout << "键值:" << (*it).first << " " << "实值:" << it->second << " ";// 	cout << endl;// }/*基于范围for循环:注意这里的元素类型为二元组for (pair<int,int> mm : m){cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";cout << endl;}*//*auto最好用,没有之一for (auto mm:m){cout << "键值:" << mm.first << " " << "实值:" << mm.second << " ";cout << endl;}*/
}// 1. map构造和赋值
void test0()
{// 默认构造 map 容器map<int, int> m;// 插入键值对m.insert(pair<int, int>(1, 3));m.insert(pair<int, int>(4, 0));m.insert(pair<int, int>(1, 3));  // 重复键值不会插入m.insert(pair<int, int>(4, 9));  // 键值相同,实值不同,仍然只保留键值唯一的元素m.insert(pair<int, int>(5, 100));print(m);// 拷贝构造map<int, int> m2(m);  // 用 m 初始化 m2print(m2);// 赋值操作map<int, int> m3 = m2;  // 将 m2 的内容赋给 m3print(m3);
}// 2. map大小和交换
void test1()
{map<int, int> m;// 插入键值对m.insert(pair<int, int>(1, 3));m.insert(pair<int, int>(2, 0));m.insert(pair<int, int>(5, 3));// 判断 map 是否为空if (m.empty()){cout << "m为空!" << endl;}else{cout << "m的长度为:" << m.size() << endl;}// 交换两个 map 容器map<int, int> m1;m1.insert(pair<int, int>(3, 1));m1.insert(pair<int, int>(4, 1));m1.insert(pair<int, int>(5, 3));cout << "交换前:" << endl;cout << "m: " << endl;print(m);cout << endl << "m1: " << endl;print(m1);// 执行交换m.swap(m1);cout << "交换后:" << endl;cout << "m: " << endl;print(m);cout << endl << "m1: " << endl;print(m1);
}// 3. map插入和删除
void test2()
{map<int, int> m;// 插入键值对的不同方法m.insert(pair<int, int>(1, 1));                // 方法一:pairm.insert(make_pair(2, 100));                   // 方法二:make_pairm.insert(map<int, int>::value_type(3, 44));    // 方法三:value_typem[4] = 55;                                     // 方法四:中括号操作符print(m);// 删除元素m.erase(m.begin());    // 删除迭代器指向的元素print(m);m.erase(3);            // 删除键值为3的元素print(m);m.erase(m.begin(), m.end());    // 删除区间中的所有元素//等价于m.clear();print(m);
}// 4. map查找和统计
void test3()
{map<int, int> m;m[0] = 45;m[4] = 34;m[5] = 0;// 查找键值为4的元素map<int, int>::iterator it = m.find(4);if (it != m.end()){cout << "查找成功:" << it->first << " " << it->second << endl;}else{cout << "查找失败" << endl;}// 统计键值为0的元素个数if (m.count(0)){cout << "查找成功" << endl << "数量为:" << m.count(0) << endl;}else{cout << "查找失败" << endl;}
}// 5. map排序:键值默认从小到大排序
void test4()
{// 默认升序排序map<int, int> m;m[0] = 11;m[1] = 23;m[-22] = 56;print(m);// 使用 greater<int> 进行降序排序map<int, int, greater<int>> m1;m1[0] = 11;m1[1] = 23;m1[-22] = 56;print1(m1);
}int main()
{test0();test1();test2();test3();test4();return 0;
}

9.相关注意事项

9.1. 键的唯一性

map 中的键必须是唯一的。这意味着你不能在 map 中插入具有相同键的多个元素。如果尝试插入一个已存在的键,map 将保持原来的值,不会更新或插入新的键值对。

map<int, int> m;
m.insert(make_pair(1, 100)); // 插入键值对 (1, 100)
m.insert(make_pair(1, 200)); // 插入失败,键 1 已存在cout << "键值:" << m[1] << endl; // 输出 100

如果你希望插入时更新键值,可以使用 [] 操作符

m[1] = 200; // 更新键 1 的值为 200

9.2. 使用 [] 操作符时的注意

当你使用 map[key] 来访问键时,如果该键不存在,map 会默认插入该键,并将值初始化为零或默认值。这可能导致意外的元素插入。

map<int, int> m;
int value = m[5];  
// 键 5 不存在,map 会自动插入键 5,其值为 0
cout << "m[5] = " << value << endl; // 输出 m[5] = 0

为避免这种行为,可以使用 find() 来检查键是否存在:

if (m.find(5) != m.end()) 
{cout << "键 5 存在" << endl;
}
else 
{cout << "键 5 不存在" << endl;
}

9.3. 修改键

map 不允许修改键。一旦键被插入到 map 中,它的值可以被修改,但键不能被更改。如果需要修改键,必须先删除该键,然后再插入新的键值对。

map<int, int> m;
m.insert(make_pair(1, 100));
m.begin()->first = 2;  // 错误,不能修改键

9.4. 避免重复插入(了解)

插入元素时,检查是否成功非常重要。map 的 insert() 函数返回一个 pair,其中 second 元素为 bool 值,指示插入是否成功。如果插入失败(因为键已存在),second 会是 false。

pair<map<int, int>::iterator, bool> ret = m.insert(make_pair(1, 100));
if (!ret.second){cout << "插入失败,键 1 已存在" << endl;
}

9.5. 迭代器失效

在 map 中,插入或删除元素时,当前的迭代器不会失效。唯一会使迭代器失效的操作是删除迭代器指向的元素。 因此,当你删除某个元素时,确保适当地处理迭代器,以避免使用失效的迭代器。

for (auto it = m.begin(); it != m.end(); ) 
{if (it->first == 3) {it = m.erase(it);  // erase 返回下一个有效的迭代器} else {it++;  // 手动递增迭代器}

}

9.6总结

  • 唯一键:map 不允许重复键,插入相同键时会保持原值。

  • [] 操作符自动插入:使用 [] 时要小心自动插入不存在的键。

  • 不可修改键:map 中键值对的键不可修改,只能删除后重新插入。

  • 避免迭代器失效:特别是在删除元素时,确保适当处理迭代器。

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

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

相关文章

Docker:SpringBoot项目创建Docker镜像并推送到阿里云容器镜像仓库

0. 准备工作 os&#xff1a;macos 15.0 jdk&#xff1a;1.8 docker&#xff1a;26.0.0 1. 阿里云容器镜像服务创建实例 创建个人版 个人实例创建成功 个人镜像加速器地址 2. 安装Docker Desktop Docker Desktop是Docker的一个集成工具&#xff0c;非必须&#xff0c;过程…

Vscode运行Python无法导入自己编写的包的解决方法

前言 在Vscode编辑器中&#xff0c;我经常用于编写Python代码&#xff0c;这一过程中&#xff0c;无论是导入第三方包还是Python内置的包&#xff0c;都未曾遇到过任何问题。然而&#xff0c;当我尝试导入一个跨文件自定义的包时&#xff0c;却遭遇了导入异常的问题。这一经历…

【例题】lanqiao153 洁净数

解题思路 通过枚举1-n的数&#xff0c;判断其是否为洁净数求解。 洁净数的判断&#xff1a;i%102判断此时的个位是不是2&#xff0c;ii//10把前一位移动到个位 # 小明非常不喜欢数字 2&#xff0c;包括那些数位上包含数字 2 的数。如果一个数的数位不包含数字 2&#xff0c;…

C++中的容器——vector

1. vector的介绍 vector&#xff1a;vector的底层实际上就是一个数组&#xff08;也称为顺序表&#xff09;&#xff0c;数据是连续存储在数组中的&#xff0c;因此vector是可以使用下标来进行访问的&#xff0c;但是它的大小并不是像数组一样是固定的&#xff0c;而是可以动态…

java基础知识20 Intern方法的作用

一 Intern方法作用 1.1 Intern方法 1.在jdk1.6中&#xff1a; intern()方法&#xff1a;在jdk1.6中&#xff0c;根据字符串对象&#xff0c;检查常量池中是否存在相同字符串对象 如果字符串常量池里面已经包含了等于字符串X的字符串&#xff0c;那么就返回常量池中这个字符…

从零开学C++:多态

引言&#xff1a;在我们去购买汽车票的时候&#xff0c;我们总会遇到成人全价&#xff0c;学生打折的情况。不同的对象&#xff08;成人、学生&#xff09;进行同一操作&#xff08;购买车票&#xff09;&#xff0c;得到不同的结果&#xff08;全价、打折&#xff09;&#xf…

2024年CAD图纸加密软件|加密图纸软件推荐:10款高效CAD加密软件

在当今数字化时代&#xff0c;CAD图纸已成为工程设计、建筑规划、机械制造等领域不可或缺的重要文件。然而&#xff0c;随着数据泄露和信息安全问题的日益严重&#xff0c;保护CAD图纸的安全性变得尤为重要。为了确保设计数据的安全&#xff0c;使用高效的CAD图纸加密软件成为了…

Stack类:常见方法讲解、使用场景、底层实现及算法问题

Stack 类是 Java 集合框架中的一个经典类&#xff0c;用于实现后进先出&#xff08;LIFO, Last In First Out&#xff09;数据结构。虽然 Stack 类作为一种直接的堆栈实现存在&#xff0c;但在开发中&#xff0c;Deque 或 LinkedList 更常被推荐用于堆栈的实现。不过&#xff0…

为什么说Claude3.5 sonnet好于GPT4O?实为网友们的无耐选择

引言 写作时&#xff0c;选择合适的工具就像船长选择航行的船只。语言模型作为目前最流行的技术工具之一&#xff0c;涉及每个人的生活与工作。Claude和GPT-4o是两款备受关注的语言模型&#xff0c;许多人自然而然地将二者进行比较&#xff0c;认为Claude更优。然而&#xff0…

时间复杂度计算 递归(solve2 后续)

原帖 最近校内比较忙&#xff0c;更新缓慢&#xff0c;致歉。 这里函数每次都需要遍历 h h h 和 m m m 之间的数&#xff08;复杂度 O ( n ) O(n) O(n)&#xff09;&#xff0c;所以和 solve1 略有不同。仍然假设 T ⁡ ( n ) \operatorname{T}(n) T(n) 表示 m − h 1 n…

python五子棋之对战项目源码【免费】

五子棋之对战项目是一种基于五子棋游戏规则的在线或本地对战项目。五子棋作为一种两人对弈的纯策略型棋类游戏&#xff0c;具有简单易学、策略性强的特点&#xff0c;因此非常适合作为对战项目的核心玩法。这个项目源码是使用Python编程语言实现的 源码下载地址&#xff1a; …

STL相关简介

string 看到这个词&#xff0c;相信大家一定都很好奇什么是string&#xff0c;它有什么作用呢&#xff1f;今天&#xff0c;就让我们一起来了解一下关于string的简介吧~ 目录 string 1. 什么是STL 2. STL的版本 3. STL的六大组件 4. STL的重要性 5. 如何学习STL 6.STL的…

【3D打印】使用simplify 3D切片更改Gcode手动断电续打、掉电、未打完继续打印、补救

一、问题描述 有些时候会遇到3D打印机没料但机器还在继续打、掉电重启后未正常恢复打印、挤出机端没有料但断料检测未触发等情况。我们又不想打印放弃&#xff0c;但又想继续之前的进度打印。 这时候我们需要更改3D打印文件的切片参数来进行继续打印。 图中问题&#xff1a;可…

知识图谱与异构图神经网络(7)--1

知识图谱是由实体(节点)和关系( 不同类型的边) 组成的多关系图。作为一种非常重要又特殊的图结构数据&#xff0c;知识图谱被广泛应用在人工智能和自然语言处理领域&#xff0c;从语义解析、命名实体消歧到问答系统、推荐系统中都可以看到来自知识图谱的技术推动。本质上&#…

微服务下设计一个注解标识是否需要登录

需求 现在我们是微服务系统&#xff0c;需要设计一个注解 RequiredLogin &#xff0c;当标识这个注解时表示系统需要登录才能继续操作。 实现思路 首先&#xff0c;需要明确我们要拦截的是从浏览器过来的请求&#xff0c;服务之间的互相调用是不需要拦截的&#xff08;比如 …

【python设计模式1】面向对象设计原则

目录 设计模式分类 面向对象 接口 面向对象设计原则 里氏替换原则 依赖倒置原则 接口隔离原则 单一职责原则 设计模式是对软件设计中普遍存在或反复出向的各种问题所提出的解决方案。每一个设计模式系统地被命名、解释和评价了面向对象系统中一个重要和重复出现的设计。…

基于MicroPython的ESP32控制LED灯闪烁设计方案的Wokwi仿真

以下是一个基于MicroPython的ESP32控制LED灯闪烁设计方案的Wokwi仿真&#xff1a; 一、硬件准备&#xff1a; 在Wokwi仿真平台(https://wokwi.com/)选择ESP32开发板&#xff0c;添加一个LED灯&#xff0c;和一个220欧姆限流电阻。 二、硬件连接&#xff1a; 1. 将LED灯的阳极…

【例题】lanqiao4403 希尔排序模板题

插入排序每次只能将数据移动一位。 已知插入排序代码为&#xff1a; def insert_sort(a):for i in range(1,len(a)):ji-1while j>0 and a[j]>a[i]:a[j1]a[j]j-1a[j1]a[i]return a希尔排序在插入排序的基础上&#xff0c;将数据移动n/2,n/4,…,1位。 for i in range(ga…

Git:Git管理

目录 Git 文件管理检测文件状态 status跟踪新文件 add提交更新 commit撤销提交 Commit Git 校验和历史查看 log版本回退 resetgit 忽略文件 Git 分支管理Git 提交对象Git master分支Git 分支管理本地分支管理远程分支管理分支hotfix处理 Git 工作流常见分支冲突处理分支合并冲突…

冒泡排序的C++语言实现(不用std::sort)

自己写一个冒泡排序的代码。 void vSort(std::vector<int> & vec, bool bDescending) {//冒泡排序int iTail vec.size()-1;while(iTail > 0){for(int k 0; k < iTail; k){int f1 vec.at(k);int f2 vec.at(k1);if(f1 < f2){//默认是降序int iTmp vec.a…