【C++提高编程-03】----C++之STL常用容器基础实战

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页:@一伦明悦-CSDN博客

✍🏻 作者简介: C++软件开发、Python机器学习爱好者

🗣️ 互动与支持💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论,

点赞加收藏支持我,点击关注,一起进步!

前言

     STL(Standard Template Library)是C++标准库中的一个重要组成部分,提供了一系列通用的模板类和函数,用于实现常见的数据结构和算法。STL容器是STL中最常用的组件之一,用于存储和管理数据。以下是关于STL容器的详细介绍:

  1. 序列容器

    • vector:动态数组,支持随机访问和动态大小调整。
    • deque:双端队列,支持在两端快速插入和删除元素。
    • list:双向链表,支持高效的插入和删除操作。
  2. 关联容器

    • set:基于红黑树的有序集合。
    • map:基于红黑树的有序映射(键-值对)。
    • multiset:允许重复值的有序集合。
    • multimap:允许重复键的有序映射。
  3. 无序关联容器

    • unordered_set:基于哈希表的无序集合。
    • unordered_map:基于哈希表的无序映射。
    • unordered_multiset:允许重复值的无序集合。
    • unordered_multimap:允许重复键的无序映射。
  4. 容器适配器

    • stack:栈,基于deque或list实现。
    • queue:队列,基于deque或list实现。
    • priority_queue:优先队列,基于vector实现。
  5. 智能指针

    • shared_ptr:共享所有权的智能指针,基于引用计数实现。
    • unique_ptr:独占所有权的智能指针,禁止复制。
    • weak_ptr:弱引用智能指针,不增加引用计数。

        STL容器提供了丰富的接口和算法,使得数据的存储、操作和管理变得更加便捷和高效。在使用STL容器时,可以根据具体需求选择合适的容器类型,并结合迭代器、算法等功能来完成复杂的数据处理任务。STL容器的广泛应用也使得C++成为一种强大的编程语言,适用于各种领域的开发和编程。

正文

01-STL基础知识

        STL(Standard Template Library)是C++标准库的一部分,提供了一套通用的模板类和函数,用于实现常见的数据结构和算法。STL包括容器(Containers)、算法(Algorithms)和迭代器(Iterators)三大组件,为C++程序员提供了丰富、高效的数据结构和算法支持。

/*  长久以来,软件界一直希望建立一种可重复利用的东西
    C++的面向对象和泛型编程思想,目的就是复用性的提升
    大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作
    为了建立数据结构和算法的一套标准,诞生了STL
*/

//  STL(Standard Template Library,标准模板库)
//  STL广义上分为容器(container)、算法(algorithm)、迭代器(iterator)
//  容器和算法之间通过迭代器进行无缝连接。
//  STL 几乎所有的代码都采用了模板类或者模板函数

//  STL六大组件:容器,算法,迭代器,仿函数,适配器,空间配置器

/*  1、容器分为两种  12354
    序列式容器: 强调值的排序,序列式容器中的每个元素均有固定的位置。 12354   按初始位置
    关联式容器: 二叉树结构,各元素之间没有严格的物理上的顺序关系     12345   按顺序排序
*/


/*  2、质变算法和非质变算法。    12345
    质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等      1234  改变值
    非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等    12345  并未改变

*/

/*  3、提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。
      每个容器都有自己专属的迭代器,迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针

      双向迭代器 读写操作,并能向前和向后操作 读写,支持++、--,

      随机访问迭代器  读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器
      读写,支持++、--、[n]、-n、<、<=、>、>=
      常用的容器中迭代器种类为双向迭代器,和随机访问迭代器

*/

        容器(Containers)

  • 容器是STL中最重要的组成部分之一,用于存储和管理数据。常见的STL容器包括 vector、deque、list、set、map 等。下面以 vector 和 map 容器为例进行具体的代码分析:

  • vector(动态数组):用于存储动态大小的元素序列,支持随机访问和动态增删操作,是使用最频繁的容器之一。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 创建一个存储 int 类型数据的 vector
    vector<int> vec;

    // 向 vector 中添加数据
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);

    // 遍历 vector 中的数据
    for (int i = 0; i < vec.size(); ++i) {
        cout << vec[i] << " ";
    }

    return 0;
}

        map(映射):用于存储键值对的集合,支持快速的查找和插入操作,适合用于建立键到值的映射关系。

#include <iostream>
#include <map>
using namespace std;

int main() {
    // 创建一个存储 string 类型键和 int 类型值的 map
    map<string, int> myMap;

    // 插入键值对
    myMap["apple"] = 10;
    myMap["banana"] = 20;
    myMap["orange"] = 30;

    // 遍历 map 中的键值对
    for (const auto &pair : myMap) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

        算法(Algorithms)

  • STL中还提供了丰富的算法函数,用于对容器中的数据进行操作,例如排序、查找、变换等。这些算法函数可以结合容器和迭代器进行灵活的数据处理。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5};

    // 对 vector 中的数据进行排序
    sort(vec.begin(), vec.end());

    // 遍历排序后的 vector
    for (int num : vec) {
        cout << num << " ";
    }

    return 0;
}

         STL通过提供丰富、高效的容器和算法,简化了C++程序的开发过程,提高了代码的可读性和可维护性。程序员可以灵活运用STL中的容器和算法来处理数据,在实际开发中大大提高了开发效率。通过深入学习STL的使用,程序员能够更好地掌握C++编程技能,写出高质量的代码。

02-Vector数组-存放内置数据类型

        Vector是C++标准库中的一种容器,用于存储一组同类型的元素,其中也可以存放内置数据类型。下面详细解释Vector数组存放内置数据类型的相关内容:

  1. 定义和声明

    • 使用vector需要包含头文件 <vector>
    • 可以通过声明 vector<数据类型> 变量名 来定义一个vector。
  2. 初始化

    • 可以通过赋值语句、列表初始化、拷贝初始化等方式进行初始化。
  3. 插入和删除元素

    • 使用 push_back() 方法在vector末尾插入元素。
    • 使用 pop_back() 方法删除vector末尾的元素。
    • 使用 insert() 方法在指定位置插入元素。
    • 使用 erase() 方法删除指定位置或指定范围的元素。
  4. 访问元素

    • 可以使用下标访问 [] 或 at() 方法访问指定位置的元素。
    • 可以使用迭代器进行元素访问。
  5. 动态调整大小

    • Vector可以动态调整大小,即在运行时改变元素数量,使用 resize() 方法实现。
  6. 内存管理

    • Vector自动管理内存,当元素数量超过当前容量时,会自动扩展容量以容纳更多元素。
  7. 常用操作

    • size():返回vector中元素的个数。
    • empty():判断vector是否为空。
    • clear():清空vector中的所有元素。
    • swap():交换两个vector的内容。

示例代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 定义一个存放整数的vector
    vector<int> vec;

    // 向vector中插入元素
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);

    // 遍历vector并输出元素
    for (int i = 0; i < vec.size(); ++i) {
        cout << vec[i] << " ";
    }
    cout << endl;

    // 使用迭代器访问元素
    vector<int>::iterator it;
    for (it = vec.begin(); it != vec.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;

    // 删除末尾的元素
    vec.pop_back();

    // 重新遍历vector并输出元素
    for (int num : vec) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

        下面给出具体代码分析应用过程:这段代码主要展示了使用vector存放内置数据类型(这里是整型数据)并遍历输出的过程。以下是对这部分代码的简要分析:

        头文件引入和命名空间声明:引入了 <iostream><vector> 和 <algorithm> 头文件。使用了 std 命名空间,可以直接使用 std::cout 和 std::endl 等符号,避免了在代码中频繁写 std::

        定义了自定义函数 myPrint:函数 myPrint 的作用是输出传入的整数参数,并换行。该函数用于 for_each 算法的回调函数。

   test01 函数:在函数 test01 中,首先创建了一个 vector<int> 容器 v,并向其中插入了四个整数元素(10、20、30、40)。注释掉了使用迭代器进行遍历的代码,通过两种不同的注释掉代码段可以看到迭代器遍历方式的不同,包括 while 和 for 循环遍历方式。使用 for_each 算法对 v 容器中的元素进行遍历,并通过回调函数 myPrint 输出每个元素。

   main 函数:在 main 函数中调用了 test01 函数,展示了如何使用 vector 存放数据并进行遍历输出。最后通过 system("pause") 命令使程序在执行完毕后暂停,防止窗口一闪而过。

        总体来说,这段代码通过展示了使用 vector 存放整型数据并使用不同的方法进行遍历输出,同时使用 for_each 算法简化了遍历的过程。通过这段代码可以了解如何使用 vector 容器和一些基本的STL算法,提高代码的可读性和简洁性。

#include <iostream>
using namespace std;
#include <vector>     // 包含数组容器的头文件
#include <algorithm>   // 使用STL中包含的算法时,必须包含这个头文件

// vector 存放内置数据类型   和模板那里很像

void myPrint(int val)
{
	cout << val << endl;
}

void test01()
{
	// 创建一个int类型的vector容器,数组
	vector<int> v;

	// 向容器中插入数据
	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);

	// 通过迭代器访问元素   iterator 迭代器相当于一个指针,因此取出数据时使用解引用方式
// 	vector<int>::iterator itBegin = v.begin();  // 起始迭代器,指向容器中第一个元素
// 	vector<int>::iterator itEnd = v.end();      // 结束迭代器,指向容器中最后一个元素的后面一个位置,相当于指向空元素
// 
// 	// 第一种遍历方式
// 	while (itBegin!=itEnd)     // 这里需要加一个判断语句,当元素指向到于itEnd相同时,则不再进行输出
// 	{
// 		cout << *itBegin << endl;  // 容器相当于一个指针,使用解引用的方式取出数据
// 		itBegin++;            // 指针遍历数组,需要对指针进行++操作,因为数组中一个元素占有4个字节,而指针也是占有4个字节
// 
// 	}

	// 第二种方式,使用for循环  第一种太过于复杂
// 	for (vector<int>::iterator it = v.begin(); it != v.end();it++)
// 	{
// 		cout << *it << endl;
// 	}
	// 第三中使用算法  遍历算法 for_each 
	for_each(v.begin(), v.end(), myPrint);   // 算法中传入三个参数  起始迭代器,结束迭代器,函数回调
	//  这里myPrint()函数传入参数为使用指针的主要原因,是因为,算法内部已经做了解引用的操作,因此返回的就是一个整型数据,并不是地址,
	//  那么函数中传入参数,也不需要在加指针



}

int main() {
    
	test01();
	system("pause");
	return 0;
}

03-Vector存放自定义数据类型

        当向vector容器中存放自定义的数据类型时,通常需要注意以下几个方面:

  1. 定义自定义数据类型

    • 首先需要定义一个自定义的数据类型,可以是类或结构体。这个数据类型可以包含多个不同类型的成员变量,表示自定义的数据结构。
    • 在定义类或结构体时,通常需要重载比较运算符或提供自定义的排序规则,以便在vector中对自定义数据类型进行排序和查找操作。
  2. vector中存储自定义数据类型

    • 创建一个vector容器,容器的模板参数为自定义的数据类型。
    • 使用push_back()函数向vector容器中添加自定义数据类型的对象。
  3. 遍历和访问

    • 可以通过下标操作或迭代器遍历vector中存储的自定义数据类型对象。
    • 也可以使用算法函数对vector中的自定义数据类型对象进行处理,比如排序、查找等操作。

        下面是一个简单的示例代码,展示了如何在vector容器中存储自定义的数据类型(这里以学生类为例)并遍历输出:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 自定义学生类
class Student {
public:
    string name;
    int age;

    Student(string n, int a) : name(n), age(a) {}
};

// 打印学生信息的函数
void printStudent(const Student &s) {
    cout << "Name: " << s.name << ", Age: " << s.age << endl;
}

int main() {
    // 创建一个存放学生对象的vector
    vector<Student> students;

    // 向vector中插入学生对象
    students.push_back(Student("Alice", 20));
    students.push_back(Student("Bob", 22));
    students.push_back(Student("Cathy", 21));

    // 遍历vector并输出学生信息
    for_each(students.begin(), students.end(), printStudent);

    return 0;
}

        下面给出具体代码分析应用过程:这段代码演示了在vector容器中存放自定义数据类型(Person类)的两种方式:一种是存放对象本身,另一种是存放对象的指针。接下来是对这段代码的简要解释:

  1. 定义自定义数据类型 Person

    • Person 类包括 m_Name 和 m_Age 两个成员变量,分别表示人的姓名和年龄。
    • 类中定义了构造函数,用来初始化 Person 对象的姓名和年龄。
  2. test01 函数

    • 首先创建一个vector<Person>类型的容器v
    • 实例化了五个 Person 对象,并通过push_back方法将它们添加到容器中。
    • 使用迭代器遍历容器中的元素,通过 it->m_Name 和 it->m_Age 访问每个 Person 对象的姓名和年龄进行输出。
  3. test02 函数

    • 创建了一个vector<Person*>类型的容器v,存放的是 Person 对象的指针。
    • 将五个 Person 对象的地址添加到容器中。
    • 使用迭代器遍历容器中的元素,通过 (*it)->m_Name 和 (*it)->m_Age 访问每个 Person 对象的姓名和年龄进行输出,这里使用指针的箭头操作符 -> 来访问指针指向的对象的成员变量。
  4. main 函数

    • 在 main 函数中依次调用了 test01 和 test02 函数,展示了两种不同存储方式的遍历输出结果。
    • 最后通过 system("pause"); 命令使程序在执行完毕后暂停,防止窗口一闪而过。

        通过这段代码,展示了如何在vector容器中存放自定义数据类型对象或指针,并通过迭代器遍历容器中的元素进行访问和输出。同时也展示了对象指针和对象本身在vector中的存储和访问方式的差异。

#include <iostream>
using namespace std;
#include<vector>
#include<string>

// vector存放自定义数据类型   自定义person类型

class Person
{


public:

	// 使用构造函数赋初值
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	

	string m_Name;
	int m_Age;
};

void test01()
{

	vector<Person>v;

	// 创建实例化对象
	Person p1("A", 10);
	Person p2("B", 20);
	Person p3("C", 30);
	Person p4("D", 40);
	Person p5("E", 50);

	// 向容器中插入数据
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);
	v.push_back(p4);
	v.push_back(p5);

	// 遍历容器中元素

	for (vector<Person>::iterator it = v.begin(); it != v.end();it++)// 这里直接it++
	{
		// *it解引用出来的就是Person数据类型,如果需要用的话直接查找类里的成员属性即可
//		cout << "姓名:"<<(*it).m_Name <<" 年龄:"<<(*it).m_Age<< endl;   // 这里相当于又创建了实例化对象,需要取出成员属性
		cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;  // 因为it就是指针,也可以这样使用
	}


}

// 存放自定义数据类型   指针

void test02()
{
	vector<Person*>v;

	// 创建实例化对象
	Person p1("A", 10);
	Person p2("B", 20);
	Person p3("C", 30);
	Person p4("D", 40);
	Person p5("E", 50);

	// 向容器中插入数据
	v.push_back(&p1);
	v.push_back(&p2);
	v.push_back(&p3);
	v.push_back(&p4);
	v.push_back(&p5);

	// 现在存放进去的是一个地址,遍历方式
	for (vector<Person*>::iterator it = v.begin(); it != v.end();it++)
	{
		// 上面(*it)返回就是一个Person数据类型,相当于实例化对象,直接.成员属性就行
		// 而这里(*it)返回的是一个Person*数据类型,(*it)是Person类的指针,使用->取出数据
		cout << "姓名:" << (*it)->m_Name << " 年龄:" << (*it)->m_Age << endl;
	}
}


int main() {

	test01();
	test02();
	system("pause");
	return 0;
}

04-Vector容器嵌套容器

       当涉及到在vector容器中嵌套另一个容器时,通常会有一些需要注意的方面。这种情况下,你可以创建一个容器,该容器的元素是另一个容器,从而实现嵌套的效果。下面是关于在vector容器中嵌套容器的详细解释:

  1. 定义嵌套容器

    • 首先,需要定义内部容器和外部容器的数据类型。内部容器可以是任何STL容器,比如vectorlist等。
    • 外部容器的元素类型是内部容器,因此外部容器的模板参数是内部容器的类型。
  2. 操作嵌套容器

    • 创建外部容器时,需要指定内部容器的类型。
    • 向外部容器中添加元素时,每个元素都是一个内部容器的实例。
    • 可以通过外部容器的迭代器来遍历外部容器,并通过内部容器的迭代器来访问和操作内部容器中的元素。

        下面是一个简单的示例代码,演示了如何在vector容器中嵌套vector容器,并对嵌套容器进行操作:

        在这个示例代码中,nestedVector是一个vector容器,其中每个元素都是一个vector<int>类型的容器。通过将内部vector容器作为外部vector容器的元素,实现了嵌套容器的效果。通过两层循环,可以遍历外部容器和内部容器,并访问内部容器中的元素。

        嵌套容器提供了一种组织数据的方式,特别适用于需要多维数据结构的场景,如二维矩阵、多级索引等。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 定义外部容器,元素类型是内部容器
    vector<vector<int>> nestedVector;

    // 添加内部容器到外部容器中
    nestedVector.push_back(vector<int>{1, 2, 3});
    nestedVector.push_back(vector<int>{4, 5});
    nestedVector.push_back(vector<int>{6, 7, 8, 9});

    // 遍历外部容器并访问内部容器中的元素
    for (const auto& innerVec : nestedVector) {
        for (int num : innerVec) {
            cout << num << " ";
        }
        cout << endl;
    }

    return 0;
}

        下面给出代码详细分析一下应用过程:这段代码演示了在vector容器中嵌套另一个vector容器的情况。下面是对代码的简要解释:

  1. 定义嵌套容器

    • 创建了一个外部vector<vector<int>>类型的容器v,其中每个元素都是一个内部vector<int>类型的容器。
    • 同时,定义了四个内部vector<int>类型的容器v1v2v3v4
  2. 操作内部容器

    • 在内部容器中,使用push_back方法向每个容器中插入一些整数数据。
  3. 将内部容器添加到外部容器

    • 将四个内部容器v1v2v3v4添加到外部容器v中,这样外部容器中就包含了四个内部容器。
  4. 遍历嵌套容器

    • 使用外部容器的迭代器遍历外部容器,得到内部容器。
    • 对于每个内部容器,再次使用内部容器的迭代器遍历,输出其中的元素。

        通过这段代码,展示了如何在vector容器中嵌套另一个vector容器,并且使用迭代器对嵌套容器进行遍历和访问。

#include <iostream>
using namespace std;
#include<vector>
#include<string>


// 容器嵌套容器


void test01()
{
	vector<vector<int>>v;   // 这里就相当于在大容器中,又加入了小容器,为int类型的数组

	// 在定义小容器
	vector<int>v1;
	vector<int>v2;
	vector<int>v3;
	vector<int>v4;
	// 小容器中插入数据   这一步是向小容器中插入数据,
	for (int i = 0; i < 4;i++)
	{
		v1.push_back(i + 1);
		v2.push_back(i + 2);
		v3.push_back(i + 3);
		v4.push_back(i + 4);
	}
	// 将容器元素插入到大容器中   这一步大容器中也需要有数据
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);

	// 使用大容器遍历小容器
	for (vector<vector<int>>::iterator it = v.begin(); it != v.end();it++)
	{
		// 这个时候可以看出来 *it 返回的是一个vector<int> 也就是有时一个容器,因此还需要一次遍历
		for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end();vit++)
		{
			cout << *vit << " ";
		}
		cout << endl;

	}


}

int main() {

	test01();
	system("pause");
	return 0;
}

        实例结果如下图所示: 

总结

     STL(Standard Template Library,标准模板库)是 C++ 标准库的一部分,提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。以下是关于STL基础知识的总结:

  1. 容器(Containers)

    • 向量(Vector):动态数组,支持快速随机访问和在末尾插入元素。
    • 链表(List):双向链表,支持在任意位置进行插入和删除操作。
    • 队列(Queue):先进先出的队列。
    • 栈(Stack):后进先出的栈。
    • 映射(Map):关联数组,存储键-值对,并根据键快速查找值。
  2. 迭代器(Iterators)

    • 迭代器用于遍历容器中的元素,提供了统一的访问容器元素的接口。
    • 包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。
  3. 算法(Algorithms)

    • STL提供了各种算法,如排序、查找、变换和合并等。
    • 可以通过算法与迭代器结合对容器进行各种操作。
    • 一些常见算法包括sortfindtransformmerge等。
  4. 函数对象(Functors)

    • 函数对象是重载了operator()的类,可以像函数一样调用。
    • 可以自定义函数对象,并将其用于算法中,比如排序或查找。
  5. 适配器(Adapters)

    • 堆栈适配器(Stack Adapter):基于vectordeque实现的栈。
    • 队列适配器(Queue Adapter):基于dequelist实现的队列。
  6. 分配器(Allocators)

    • 分配器用于管理内存分配。
    • 可以自定义分配器并用于 STL 容器。
  7. 内置类型(Basic Types)

    • STL包含了一些内置类型,如pair用于存储一对值、tuple用于存储任意数量的值。

        总的来说,STL提供了一组灵活、高效且通用的工具,能够帮助我们更方便地实现各种数据结构和算法。熟练掌握STL的基础知识对于C++编程是非常重要的。   

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】必会降维算法之:t-分布邻域嵌入(t-SNE)

t-分布邻域嵌入&#xff08;t-SNE&#xff09; 1、引言2、随机梯度下降&#xff08;SGD&#xff09;2.1 简介2.1.1 定义2.1.2 应用场景 2.2 原理2.3 实现方式2.4 算法公式2.5 代码示例解析&#xff1a; 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 啥是降维算法 小鱼…

(二)可视化面板:Grafana的安装

其他相关文章 &#xff08;一&#xff09;一套开源的系统监控报警框架&#xff1a;Prometheus安装 什么是grafana Grafana是一个面板(Dashboard),有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器。支持Graphite、zabbix、InfluxDB、Prometheus和OpenTSDB作为…

【汽车操作系统】Autosar和商用OS

目录 什么是AUTOSAR? CP AUTOSAR架构 CAN通信 AP AUTOSAR 背景 CP&AP 开发方面的不同&#xff1a; WRLinux介绍 QNX介绍 什么是AUTOSAR? 随着汽车功能越来越多&#xff0c;导致ECU的数量越来越多。1993年的时候&#xff0c;奥迪A8才只有5个ECU现在典型的现代汽车…

用数据,简单点!奇点云2024 StartDT Day数智科技大会,直播见

在充满挑战的2024&#xff0c;企业如何以最小化的资源投入和试错成本&#xff0c;挖掘新的增长机会&#xff0c;实现确定性发展&#xff1f; “简单点”是当前商业环境的应对策略&#xff0c;也是奇点云2024 StartDT Day的核心理念。 5月28日&#xff0c;由奇点云主办的2024 S…

分享一个思路,使用插桩技术解决慢查询测试问题

前段时间&#xff0c;我负责测试的系统在生产环境运行出现问题。该系统对于响应时间要求较高&#xff0c;问题发生的时候并发很高&#xff0c;出现大量请求超时&#xff0c;超时请求比例随时间推迟越来越高&#xff0c;最后几乎全部请求都失败。滚动重启了所有进程后&#xff0…

Leetcode刷题2

文章目录 前言寻找两个正序数组的中位数1️⃣ 双指针快速排序2️⃣ 第k小数解法 Z 字形变换1️⃣ 个人解法2️⃣巧妙解法13️⃣巧妙解法2 字符串转换整数 (atoi)1️⃣ 常规方法2️⃣ 作弊方法&#x1f62b; 整数转罗马数字1️⃣ 常规方法&#xff1a;按照给定规则写出判断条件即…

ABB机器人手动模式切换自动模式时,速度自动更改为100%的解决办法

ABB机器人手动模式切换自动模式时,速度自动更改为100%的解决办法 如下图所示,手动切换到自动模式时,示教器上提示:速度将改为100%,但是我们正常使用时的速度可能不是100%,所以还需要手动去更改速度,不太方便。。。 解决办法可参考以下内容: 如下图所示,打开菜单—控制…

防火墙技术基础篇:解析防火墙的网络隔离机制

防火墙技术基础篇&#xff1a;解析防火墙的网络隔离机制 网络安全在现代社会中扮演着重要的角色&#xff0c;保护网络系统、用户和数据免受未经授权的访问、破坏和窃取。个人、企业和国家都需要加强网络安全意识&#xff0c;采取有效措施保护自身的网络安全。随着网络攻击手段…

Golang实现递归复制文件夹

代码 package zdpgo_fileimport ("errors""os""path/filepath""strings" )// CopyDir 复制文件夹 // param srcPath 源文件夹 // param desPath 目标文件夹 // return error 错误信息 func CopyDir(srcPath, desPath string) error {…

张量 t-product 积(matlab代码)

参考文献&#xff1a;Tensor Robust Principal Component Analysis with a New Tensor Nuclear Norm 首先是文章2.3节中 t-product 的定义&#xff1a; 块循环矩阵&#xff1a; 参考知乎博主的例子及代码&#xff1a;&#xff08;t-product与t-QR分解&#xff0c;另一篇傅里叶对…

200smart【编程入门】

说明 编程时&#xff0c;遇到困难就按【F1】 【I】输入 200smart 上限 i0.0~i31.7 255bit【255个输入点】 i0.0~i31.7 八进制 【布尔 bool 】 ib0~ib127 【单字节】 8bit iw0~iw127 …

六零导航页 file.php 任意文件上传漏洞复现(CVE-2024-34982)

0x01 产品简介 LyLme Spage(六零导航页)是中国六零(LyLme)开源的一个导航页面。致力于简洁高效无广告的上网导航和搜索入口,支持后台添加链接、自定义搜索引擎,沉淀最具价值链接,全站无商业推广,简约而不简单。 0x02 漏洞概述 六零导航页 file.php接口处任意文件上传…

Java面试八股之++操作符是线程安全的吗

操作符是线程安全的吗 操作符本身在Java中并不是线程安全的。这个操作实际上包含三个步骤&#xff1a;读取变量的值、将值加1、然后将新值写回内存。在多线程环境下&#xff0c;如果多个线程同时对同一个变量执行操作&#xff0c;就可能出现竞态条件&#xff08;race conditio…

TransFormer学习之基础知识:STN、SENet、CBAM、Self-Attention

1.空间注意力机制STN 参考链接&#xff1a;STN(Spatial Transformer Networks) 参考链接&#xff1a;通俗易懂的Spatial Transformer Networks(STN) 核心动机&#xff1a; 在空间中捕获重要区域特征(如图像中的数字)&#xff0c;将核心区域进行放大居中&#xff0c;使得结果更…

K8S认证|CKA题库+答案| 7. 调度 pod 到指定节点

7、调度 pod 到指定节点 您必须在以下Clusterd/Node上完成此考题&#xff1a; Cluster Master node Worker node hk8s master …

GS5812G 21V、2A同步降压DC/DC转换器芯片IC

一般描述 该GS5812G是一个同步降压DC/DC转换器与快速恒定的时间(FCOT)模式控制。该器件提供4. 5V至21V的输入电压范围和2A连续负载电流能力。它是恒定时间脉宽调制(PWM)控制器&#xff0c;支持 FCOT模式控制。工作频率取决于输入和输出电压条件。 该GS5812G故障…

桌面藏线大法

1有线改无线&#xff1a; 蓝牙鼠标 蓝牙键盘 蓝牙耳机 2将排插贴到桌子底下 购物软件上搜 3断舍离 不要的电子产品统统扔掉 4 洞洞板和挂钩 这个不用介绍了

uniapp中使用mockjs模拟接口测试总结(swiper轮播图示例)

完整总结下在uni-app中如何使用Mock.js模拟接口测试&#xff0c;这在后台接口未就绪的情况下非常有用。同时也给出个首页swiper轮播图的mock接口使用。网上的文章都不太完整&#xff0c;这里总结下完整的使用示例&#xff0c;同时也支持h5和小程序平台&#xff0c;分享给需要的…

个人感觉对Material设计有用的几个网址

(一) Modular and customizable Material Design UI components for Android GIthub: material-components-android (二) 学习Material设计 Material Design (三) 用于创建Material主题&#xff0c;支持导出多种格式 material-theme-builder

谷歌蜘蛛池是什么?

或称为谷歌爬虫池&#xff0c;是一项专门针对谷歌搜索引擎优化&#xff08;SEO&#xff09;的先进技术&#xff0c;这种技术的主要目的是通过建立庞大的网站群体和复杂的链接结构来吸引和维持谷歌的爬虫程序的注意力&#xff0c;其核心是通过这种结构优化&#xff0c;增强特定网…