C++-模板与容器

news2024/9/20 22:51:59

1、模板

模板可以让类或者函数支持一种通用类型,这种通用类型在实际运行过程中可以使用任何数据类型。因此程序员可以写出一些与类型无关的代码。这种编程方式也叫“泛型编程”。

通常有两种形式:

  • 函数模板
  • 类模板

1.1 函数模板

//模板类型声明
template<class T>//T 模板类型

是让一个函数支持模板编程,可以使函数支持通用数据类型。

#include <iostream>
#include <string.h>
using namespace std;
// 模板函数
template<class T>//T 模板类型
add(T a,T b)
{
   return a+b;
}
int main()
{
    cout << add(1,2) << endl; // 3
    string s1 = "hello";
    string s2 = "world";
    cout << add(s1,s2) << endl; // helloworld
    cout << add(2.3,23.12) << endl;
//  cout << add(1,23.3) << endl; 
//编译器自动识别数据类型
//错误,无法推导,局限性:只能用同一种类型
//错误,两个指针无法相加,如果想要实现这个功能,想要将+运算符重载
//cout << add("hello","world") << endl;
    return 0;
}

1.2 类模板

使一个类支持模板编程,可以使类支持通用数据类型。

作用域:只有一个花括号大小

#include <iostream>
#include <string.h>
using namespace std;
// 模板函数
//template<typename T>
//T add(T a,T b)
//{
//   return a+b;
//}
template<class T>    // 可以class 也可以typename
class Test
{
private:
    T val;
public:
    Test(T v)
    {
        val = v;
    }
    T get_val()
    {
        return val;
    }
    void set_val(T v)
    {
        val = v;
    }
};
int main()
{
    // 类模板需要执行模板类型,通过<>。只要在之后的程序中看到<>,肯定是个模板类
    Test<int> t1(20);
    cout << t1.get_val() << endl;
    t1.set_val(10);
    cout << t1.get_val() << endl;
    t1.set_val(2.34);
//    cout << t1.get_val() << endl; // 数据窄化 输出2
    Test<double> t2(2.14); // 指定类模板为double
    cout << t2.get_val() << endl;
    t2.set_val(3);
    cout << t2.get_val() << endl;
    return 0;
}

类内定义,类外声明

上面的写法可以改为类内声明类外定义的形式:

#include <iostream>
#include <string.h>
using namespace std;
template<class T>    // 可以class 也可以typename
class Test
{
private:
    T val;
public:
    Test(T v)
    {
        val = v;
    }
    T get_val();//类内定义 类外声明
    void set_val(T v);
};

template<class T>
Test<T>::get_val()//类内定义 类外声明
{
    return val;
}

template<class T>
//返回值类型 模板类型作用域 函数名(传参)
void Test<T>::set_val(T v)
{
    val = v;
}

int main()
{
    Test<int> t1(20);
    cout << t1.get_val() << endl;
    t1.set_val(10);
    cout << t1.get_val() << endl;
    t1.set_val(2.34);
//    cout << t1.get_val() << endl; // 数据窄化输出2
    Test<double> t2(2.14);
    cout << t2.get_val() << endl;
    t2.set_val(3);
    cout << t2.get_val() << endl;
    return 0;
}


2、容器

2.1 标准模板库STL

标准模板库(Standard Template Library,STL)是惠普实验室开发的一系列软件的统称。虽然说它主要出现在C++中,但是它在被引入C++之前,该技术就已经存在很长时间了。

STL的代码从广义上讲分为三部分,algorithm(算法)、container(容器)、iterator(迭代器)。几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用的机会。

2.2 概念

容器是用来存储数据的集合,数据元素可以是任何类型(因为是使用模板实现的)

容器类的使用,都要引入对应的头文件。

2.3 顺序容器

顺序容器中每个元素均有固定的位置并呈线性排布。除非使用删除或者是插入操作改变元素的位置。

2.3.1 array数组

array是C++11新增的容器类型,与传统数组相比更加安全,易于使用。array数组是定长的。没法方便的伸缩。array创建数组必须是定长的,且不能用变量定长。

QMAKE_CXXFLAGS += -std=c++11

array数组常用函数

#include <array> // 头文件
array<int,5> arr = {1,2,3}; // 后面两位补零

#include <iostream>
#include <array> // 头文件
using namespace std;
int main()
{
    // 创建一个长度为5的int数组
    array<int,5> arr = {1,2,3}; // 后面两位补零
    cout << arr[0] << endl; // 1
    cout << arr[4] << endl; // 0
    cout << arr.at(2) << endl; // 3 推荐使用at
    arr[3] = 200;
    // for
    for(int i = 0; i < arr.size(); ++i)
    {
        cout << arr.at(i) << " ";
    }
    cout << endl;
    // for each
    for(int i:arr)
    {
        cout << i << " ";
    }
    cout << endl;
    //迭代器遍历,后面讲
    // TODO
    return 0;
}

2.3.2 vector 向量

vector向量内部是由数组实现的,比较适合进行随机的存取操作,不擅长插入删除操作。

不是定长,方便伸缩。(大量数据存取时且不经常插入删除)

vector向量常用函数

#include <vector> // 头文件
vector<int> vec(50);//创建一个大小为5类型为int,默认值为0的vector向量数组
vec.push_back(222);//在最后面追加新元素
vec.insert(vec.begin()+2,333);//begin()指向第一个元素位置
vec.pop_back();  // 删除最后一个元素
vec.erase(vec.end()-2);//end()指向最后一个元素后面,删除了倒数第二个元素
vec.empty()// 判断是否为空,0非空,1空
vec.clear();// 清空

#include <iostream>
#include <vector> // 头文件
using namespace std;
int main()
{
//    vector<int> vec(5,0);//创建一个大小为5类型为int,默认值为0的vector向量数组
//    cout << vec.size() << endl;
//    for(int i = 0; i < vec.size(); ++i)
//    {
//        cout << vec[i] << endl;
//    }
    vector<int> vec = {1,2,3};
    // 增
    vec.push_back(222);//在最后面追加新元素
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    cout <<"向量大小:"<< vec.size() << endl;

    // 插入操作,定向插入
    // begin()可以返回指向第一个元素的迭代器指针,+2是在第三个位置上插入333
    vec.insert(vec.begin()+2,333);//begin()指向第一个元素位置
    cout<<"定向插入:"<<endl;
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    // 删
    // 删除最后一个元素
    cout<<"删除最后一个元素:"<<endl;
    vec.pop_back();
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    // 删除了第二个元素
    cout<<"删除了第二个元素:"<<endl;
    vec.erase(vec.begin()+1);
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    // 删除了倒数第二个元素
    cout<<"删除了倒数第二个元素:"<<endl;
    vec.erase(vec.end()-2);//end()指向最后一个元素后面
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    // 改
    cout<<"改:"<<endl;
    vec[1] = 666;
    vec.at(0) = 888;
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout<<"--------------------"<<endl;
    // 查
    cout << vec[1] << endl;
    for(int i :vec)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout << "---------------------" <<  endl;

    for(int i = 0; i < vec.size(); ++i)
    {
        cout << vec[i] << " ";
    }
    cout <<  endl;

    // 判断是否为空,0非空,1空
    cout << vec.empty() << endl;

    // 清空
    vec.clear();
    cout << vec.empty() << endl;
    // 迭代器遍历先省略

    return 0;
}

2.3.3 list列表

list内部是由双向循环链表实现的。不支持下标。优点:可以高效的删除和插入操作。但不适合随机的存取操作。

list列表常用函数

#include <list> // 头文件
list<string> lis2{"hello","world"};
//创建了一个长度为2的列表,第一个元素就是hello,第二个world
list<string> lis(5,"hello");
// 创建一个长度为5的列表,每个元素都是“hello”
lis.push_back("world"); // 向后追加一个单元素
lis.push_front("hahaha");   // 向前追加一个单元素
lis.insert(++lis.begin(),"2222"); // 在第二个位置上插入“2222”,lis.begin()只能自增,不能加数值
lis.pop_back(); // 删最后一个元素
lis.pop_front();    // 删除第一个元素
lis.push_back("world"); // 向后追加一个单元素
list<string>::iterator iter = lis.begin();// 保存迭代器指针
advance(iter,1); // 移动迭代器指针

#include <iostream>
#include <list> // 头文件
using namespace std;
int main()
{
    // 创建了一个默认无数值的list
    list<string> lis1;
    //创建了一个长度为2的列表,第一个元素就是hello,第二个world
    list<string> lis2{"hello","world"};
    for(string s:lis2)
    {
        cout << s << " ";
    }
    cout <<endl;

    // 创建一个长度为5的列表,每个元素都是“hello”
    list<string> lis(5,"hello");
    cout<<"创建一个长度为5的列表,每个元素都是“hello”"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 增
    lis.push_back("world"); // 向后追加一个单元素
    cout<<"向后追加一个单元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    lis.push_front("hahaha");   // 向前追加一个单元素
    cout<<"向前追加一个单元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    lis.insert(++lis.begin(),"2222"); // 在第二个位置上插入“2222”,lis.begin()只能自增,不能加数值
    cout<<"在第二个位置上插入“2222”"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 删
    lis.pop_back(); // 删最后一个元素
    cout<<"删最后一个元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    lis.pop_front();    // 删除第一个元素
    cout<<"删除第一个元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    lis.push_back("world"); // 向后追加一个单元素
    cout<<"删除第一个元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 保存迭代器指针
    list<string>::iterator iter = lis.begin();
    advance(iter,1); // 移动迭代器指针
    lis.insert(iter,"3333");  // 插入3333
    cout<<"通过移动迭代器指针定向插入,插入3333"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 删除最后一个元素
    iter = lis.end();
    iter--;
    lis.erase(iter);//删除iter指针指向的元素
    cout<<"通过移动迭代器指针定向删除"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 返回第一个元素的引用
    cout << "打印第一个元素* = " << lis.front() << endl;
    // 返回最后一个元素
    cout << "打印最后一个元素* = " << lis.back() << endl;

    // 改
    iter = lis.end();
    advance(iter,2);//将迭代器指针移动到第二个位置
    *iter = "200";
    cout<<"通过移动迭代器指针定向修改元素"<<endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;
    // 查
    cout<<"迭代器指针查看"<<endl;
    cout << *iter << endl;
    for(string s:lis)
    {
        cout << s << " ";
    }
    cout<<endl;
    cout<<"___________________"<<endl;

    // 迭代器遍历
    cout << lis.size() << endl;
    // 清空
    lis.clear();
    cout << lis.size() << endl;
    return 0;
}

2.3.4 deque队列

deque几乎支持所有vector的API。性能位于vector与list二者之间。最擅长两端存取的顺序容器。

#include <iostream>
#include <deque> // 头文件

using namespace std;

int main()
{
//    deque<int> deq(5);
//    cout << deq.size() << endl;
//    for(int i = 0; i < deq.size(); ++i)
//    {
//        cout << deq[i] << endl;
//    }
    deque<int> deq = {1,2,3};
    // 增
    deq.push_back(222);
    cout << deq.size() << endl;
    // 插入操作
    // begin()可以返回指向第一个元素的迭代器指针,+2是在第三个位置上插入333
    deq.insert(deq.begin()+2,333);

    // 删
    // 删除最后一个元素
    deq.pop_back();

    // 删除了第二个元素
    deq.erase(deq.begin()+1);

    // 删除了倒数第二个元素
    deq.erase(deq.end()-2);

    // 改
    deq[1] = 666;
    deq.at(0) = 888;

    // 查
    cout << deq[1] << endl;
    for(int i :deq)
    {
        cout << i <<" ";
    }
    cout << endl;
    cout << "---------------------" <<  endl;

    for(int i = 0; i < deq.size(); ++i)
    {
        cout << deq[i] << " ";
    }
    cout <<  endl;

    // 判断是否为空,0非空,1空
    cout << deq.empty() << endl;

    // 清空
    deq.clear();
    cout << deq.empty() << endl;
    // 迭代器遍历先省略

    return 0;
}

2.4 关联容器

关联容器的各个元素之间没有严格顺序,虽然内部具有排序特点。但是在使用时没有任何顺序相关的接口。底层是由树构成,(红黑树)

最常见的关联容器就是map-键值对映射

对于map而言,键具有唯一性,键通常使用字符串类型,值任何类型。通过键找到对应的值。

关联容器常用函数

#include <map> // 头文件
map<string,int> ma;//创建一个value为int类型的关联容器
map<string,int> ma1 = {{"年龄",99},{"身高",250}};
ma.insert(pair<string,int>("体重",70));   // 插入元
if(ma.find("身高") == ma.end())
    {
        cout << "没有身高元素" << endl;
    }
int re = ma.erase("身高"); // 删除元素,返回值1成功,0失败

#include <iostream>
#include <map> // 头文件

using namespace std;

int main()
{
    // map创建初始化 C++11支持
    map<string,int> ma1 = {{"年龄",99},{"身高",250}};
    cout << ma1.size() << endl; // 2

    map<string,int> ma;//创建一个value为int类型的关联容器
    cout << ma.size() << endl;//0:容器大小

    // 增
    cout << "增操作:"<< endl;
    ma["身高"] = 180;
    ma.insert(pair<string,int>("体重",70));   // 插入元素
    cout <<"身高"<< ma["身高"] << endl;
    cout <<"体重"<<ma["体重"] << endl;
    cout << "--------------------" << endl;
    // 改
    cout << "改操作:"<< endl;
    ma["身高"] = 165;
    cout << "身高"<<ma["身高"] << endl;
    cout << "--------------------" << endl;
    // 查
    cout << "查操作:" << endl;
    cout << "身高"<<ma["身高"] << endl;
    if(ma.find("身高") == ma.end())
    {
        cout << "没有身高元素" << endl;
    }
    else
    {
        cout << "身高"<<ma["身高"] << endl;
    }
    cout << "--------------------" << endl;
    // 删
    cout << "删除操作前 "<<ma.size() << endl;
    cout << "删除操作:" << endl;
    int re = ma.erase("身高"); // 删除元素,返回值1成功,0失败
    cout << "身高删除返回值:" << re << endl;
    if(ma.find("身高") == ma.end())
    {
        cout << "没有身高元素" << endl;
    }
    else
    {
        cout << "身高"<<ma["身高"] << endl;
    }
    cout <<"删除操作后 "<< ma.size() << endl;
    cout << "--------------------" << endl;
    //清空操作
    cout << "清空操作" << endl;
    ma.clear();
    cout << ma.size() << endl;
    cout << "--------------------" << endl;
    return 0;
}

2.5 迭代器

迭代器是一个特殊的指针,主要用于容器的元素读写以及遍历。

如果迭代器不进行修改,建议使用只读迭代器,const_iterator,反之使用iterator.

#include <array>
#include <vector>
#include <list>
#include <deque>
#include <map> // 头文件

// 迭代器遍历 string
for(string::const_iterator iter = s.begin();iter != s.end(); ++iter)
// 迭代器遍历array
for(array<int,5>::const_iterator iter = arr.begin();iter != arr.end();iter++)
// vector 迭代器遍历
for(vector<string>::const_iterator iter = vec.begin();iter != vec.end();iter++)
// 迭代器遍历list
for(list<string>::const_iterator iter = lis.begin();iter != lis.end();++iter)
// 迭代器遍历deque
for(deque<string>::const_iterator iter = de.begin();iter != de.end();iter++)
// 迭代器遍历map
for(map<string,int>::const_iterator iter = ma.begin();iter != ma.end(); iter++)
{
    // first 是键 second 是值
    cout << iter->first << " " << iter->second << endl;
}

#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <deque>
#include <map> // 头文件

using namespace std;

int main()
{
    string s = "abdcdfg";
    // 迭代器遍历 string
    cout<<"迭代器遍历 string:"<<endl;
    for(string::const_iterator iter = s.begin();
        iter != s.end(); ++iter)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------" << endl;

    // 迭代器遍历array
    cout<<"迭代器遍历array:"<<endl;
    array<int,5> arr = {23,2,5,87,2};
    for(array<int,5>::const_iterator iter = arr.begin();
        iter != arr.end();iter++)
    {
         cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------" << endl;

    // vector 迭代器遍历
    cout<<"vector 迭代器遍历:"<<endl;
    vector<string> vec(6,"hello");
    for(vector<string>::const_iterator iter = vec.begin();
        iter != vec.end();iter++)
    {
        cout << *iter << " ";
    }

    cout << endl;
    cout << "--------------" << endl;

    // 迭代器遍历list
    cout<<"迭代器遍历list:"<<endl;
    list<string> lis(6,"world");
    for(list<string>::const_iterator iter = lis.begin();
        iter != lis.end();++iter)
    {
        cout << *iter << " ";
    }

    cout << endl;
    cout << "--------------" << endl;

    // 迭代器遍历deque
    cout<<"迭代器遍历deque:"<<endl;
    deque<string> de(6,"nihao");
    for(deque<string>::const_iterator iter = de.begin();
        iter != de.end();iter++)
    {
        cout << *iter << " ";
    }

    cout << endl;
    cout << "--------------" << endl;

    // 迭代器遍历map
    cout<<"迭代器遍历map:"<<endl;
    map<string,int> ma;
    ma["年龄"] = 23;
    ma["身高"] = 180;
    ma["体重"] = 65;

    for(map<string,int>::const_iterator iter = ma.begin();
        iter != ma.end(); iter++)
    {
        // first 是键 second 是值
        cout << iter->first << " " << iter->second << endl;
    }

    return 0;
}



练习:

写一个函数show_array,要求传入两个参数。

void show_array(T t,int len)

第一个参数为数组默认值,第二个参数为数组的长度。

此函数的功能为创建一个长度为len类型是T,默认值为t的数组并输出。

尽量不用使用c语言的数组。

#include <iostream>

#include <vector>
using namespace std;
template<class T>
void show_array(T t,int len)
{
    vector<T> vec(len,t);
    for(T i:vec)
    {
        cout << i << " ";
    }

}

int main()
{
    show_array("a",5);
    return 0;
}


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

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

相关文章

【基础篇】九、程序计数器 JVM栈

文章目录 0、运行时数据区域1、程序计数器2、JVM栈3、JVM栈--栈帧--局部变量表4、JVM栈--栈帧--操作数栈5、JVM栈--栈帧--桢数据6、栈溢出7、设置栈空间大小8、本地方法栈 0、运行时数据区域 JVM结构里&#xff0c;类加载器下来&#xff0c;到了运行时数据区域&#xff0c;即Ja…

Navicat for Mysql怎么执行创建表的脚本

Navicat for Mysql怎么执行创建表的脚本 Navicat 怎么执行sql文件 Navicat 执行创建表语句 Navicat 执行sql语句 Navicat 怎么创建表语句 1、打开Navicat数据库管理工具&#xff1b; 2、点击菜单栏上的“工具”&#xff0c;选择“命令列界面”&#xff1b; 打开了命令列界面…

Vue学习计划-Vue3--核心语法(三)computed计算属性、watch监听、watchEffect函数

1. computed计算属性 作用&#xff1a;根据已有数据计算出新数据&#xff08;和Vue2中的computed作用一致&#xff09;。 2. watch监视与watchEffect 1. watch 作用&#xff1a;监视数据的变化&#xff08;和Vue2的watch作用一致&#xff09;特点&#xff1a;Vue3中的watch…

Flume基础知识(五):Flume实战之实时监控目录下多个新文件

1&#xff09;案例需求&#xff1a; 使用 Flume 监听整个目录的文件&#xff0c;并上传至 HDFS 2&#xff09;需求分析&#xff1a; 3&#xff09;实现步骤&#xff1a; &#xff08;1&#xff09;创建配置文件 flume-dir-hdfs.conf 创建一个文件 vim flume-dir-hdfs.conf …

一起学docker(六)| Dockerfile自定义镜像 + 微服务模块实战

DockerFile 是什么 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 构建步骤 编写Dockerfile文件docker build命令构建镜像docker run运行镜像 Dockerfile构建过程 基础知识 每个保留字指令都必须为大写字母且后面…

逻辑回归(LR)----机器学习

基本原理 逻辑回归&#xff08;Logistic Regression&#xff0c;LR&#xff09;也称为"对数几率回归"&#xff0c;又称为"逻辑斯谛"回归。 logistic回归又称logistic 回归分析 &#xff0c;是一种广义的线性回归分析模型&#xff0c;常用于数据挖掘&#…

『年度总结』逐梦编程之始:我的2023学习回顾与展望

目录 这篇博客&#xff0c;我将回顾2023年编程之旅的起点&#xff0c;同时展望2024年的新征程。 前言 我与Python 我与C语言 第一篇正式博客&#xff1a; 第二篇正式博客&#xff08;扫雷&#xff09;&#xff1a; 指针学习笔记: C语言学习笔记&#xff1a; 我与数据结构…

SCT52A40——120V,4A,高频高压侧和低压侧栅极驱动器,替代UCC27200/UCC27201/MIC4604YM等

• 8-24V宽供电电压 • 驱动高侧和低侧N通道MOSFET • 4A峰值输出源电流和汇电流 • 升压电源电压范围可达120V • 集成阴极负载二极管 • TTL兼容输入&#xff0c;-10V输入 • 45ns传输延迟 • 1000pF负载下7ns上升和4.5ns下降时间 • 2ns延迟匹配时间 • 静态电流252uA • 15…

JDK、JRE、JVM的联系与区别

JDK、JRE、JVM的联系与区别 一、JDK,JRE,JVM定义 JDK(Java Development Kit),包含JRE,以及增加编译器和调试器等用于程序开发的文件。 JRE(Java Runtime Environment)&#xff0c;包含Java虚拟机、库函数、运行Java应用程序所必须的文件。 JVM(Java Virtual Machine)是一个虚…

Vue中的选项式 API 和组合式 API,两者有什么区别

Vue中的选项式 API&#xff08;Option API&#xff09;和组合式 API&#xff08;Composition API&#xff09;是两种不同的组件编写方式&#xff0c;它们各有特点和适用场景&#xff1a; 选项式 API&#xff08;Option API&#xff09;: 传统方法&#xff1a;Vue最初的编程范式…

LeetCode 热题 100——42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

一起玩儿物联网人工智能小车(ESP32)——25. 利用超声波传感器测量距离

摘要&#xff1a;本文介绍如何利用超声波传感器测量障碍物的距离 测量距离是智能小车经常要用到的功能&#xff0c;今天就来介绍一个最常用的测量距离的传感器——超声波传感器。 超声波传感器的测距原理是利用超声波发射器向某个方向发射超声波&#xff0c;与此同时&#xff…

Health System Pro - Plug Play Solution

Health System为您提供了可重复使用的健康组件、健康条和碰撞块组件&#xff0c;可以轻松定制和扩展&#xff0c;以满足任何项目的需求。通过使用Health System&#xff0c;您可以节省时间和精力&#xff0c;避免为每个项目或游戏实体重写健康逻辑&#xff0c;从而带来更高效的…

计算机网络(9):无线网络

无线局域网 WLAN 无线局域网常简写为 WLAN (Wireless Local Area Network)。 无线局域网的组成 无线局域网可分为两大类。第一类是有固定基础设施的&#xff0c;第二类是无固定基础设施的。所谓“固定基础设施”是指预先建立起来的、能够覆盖一定地理范围的一批固定基站。 …

Python----matplotlib库

目录 plt库的字体&#xff1a; plt的操作绘图函数&#xff1a; plt.figure(figsizeNone, facecolorNone): plt.subplot(nrows, ncols, plot_number)&#xff1a; plt.axes(rect)&#xff1a; plt.subplots_adjust(): plt的读取和显示相关函数&#xff1a; plt库的基础图…

Day22 二叉树part08 235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

二叉树part08 235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 235. 二叉搜索树的最近公共祖先 方法一&#xff1a;递归法&#xff08;利用二叉搜索树性质&#xff09; class Solution { public:TreeNode* lowestCommonAncestor(TreeN…

74HC595驱动数码管程序

数码管的驱动分静态扫描和动态扫描两种&#xff0c;使用最多的是动态扫描&#xff0c;优点是使用较少的MCU的IO口就能驱动较多位数的数码管。数码管动态扫描驱动电路很多&#xff0c;其中最常见的是74HC164驱动数码管&#xff0c;这种电路一般用三极管作位选信号&#xff0c;用…

管理组件状态

概述 在应用中&#xff0c;界面通常都是动态的。如图1所示&#xff0c;在子目标列表中&#xff0c;当用户点击目标一&#xff0c;目标一会呈现展开状态&#xff0c;再次点击目标一&#xff0c;目标一呈现收起状态。界面会根据不同的状态展示不一样的效果。 图1 展开/收起目标…

50、实战 - 利用 conv + bn + relu + add 写一个残差结构

上一节介绍了残差结构&#xff0c;还不清楚的同学可以返回上一节继续阅读。 到了这里&#xff0c;一个残差结构需要的算法基本都介绍完了&#xff0c;至少在 Resnet 这种神经网络中的残差结构是这样的。 本节我们做一个实战&#xff0c;基于之前几节中手写的 conv / bn 算法&…

python封装接口自动化测试套件 !

在Python中&#xff0c;我们可以使用requests库来实现接口自动化测试&#xff0c;并使用unittest或pytest等测试框架来组织和运行测试套件。以下是一个基本的接口自动化测试套件封装示例&#xff1a; 首先&#xff0c;我们需要安装所需的库&#xff1a; pip install requests …