标准模板库STL

news2024/9/28 13:24:37

一、概述

1.1 STL的概念和作用

  • STL的概念:全称为 Standard Template Library

  • STL的作用:
    首先STL并不是语言的一部分(一开始并没有)它就是一个工具库, 没有这个工具时程序员写程序都要自己做(例如:数据结构中的 链表,堆栈…)

STL模板库内部使用模板使操作更加泛化, STL内部三大部分构成(容器,泛型以及算法)

1.2 数组结构和链表结构

  • 数组结构
    优点:随机访问方便,速度快效率高。
    缺点:插入删除不方便,效率低(内存空间分布的限制)
    只要数据存储在连续内存空间中即为数组结构。

  • 链表结构
    优点:插入删除操作方便,效率高。
    缺点:随机访问不方便效率低,往往就是通过在遍历过程中对给定的条件进行检测。
    只要数据存储在非连续内存空间中,但数据之间互相关联即为链式结构。

  • 总结:STL模板库中所提供的容器类,结合了数组和链表的优缺点,使用户从诸如内存管理的细节中得以解脱(对数组和链表的操作进行了封装)

1.3 十大容器概述

  • 向量(vector):类似数组(内部是线性存储)支持下标访问,在尾部添加和删除元素效率高,中间执行添加删除操作可以,但效率很低。

  • 双端队列( deque ) : 支持下标访问(头尾两端都可添加/删除操作)。

  • 列表(list):在任何位置添加和删除操作都很方便,不支持下标访问

  • 堆栈(stack):支持在一端存储和提取元素。

  • 队列(queue):支持从前端提取,后端压入元素。

  • 优先队列(priority_queue):类似队列,但所提取的是具有最高优先级的元素(默认大者优先)。

  • 映射(map):以 key-value对 的形式存储数据,以key的升序排列,key唯一(内部结构是红黑树)。

  • 多重映射(multimap):允许key重复出现的映射。

  • 集合(set):没有value的映射 。

  • 多重集合(multiset):没有value的多重映射。

向量、双端队列和链表称为基本容器。

容器分类

  • 线性(基本)容器:(向量,双端队列,列表)这类容器元素按照线性顺序(可以通过一个元素找到它的下一个元素即为线性)排列,必须支持某种形式的next操作,以便从一个元素移动到下一个元素(迭代)。

  • 适配器容器 :(堆栈,队列,优先队列)这类容器是对线性容器的一些接口加以屏蔽的产物。

  • 关联容器 :(映射,多重映射,集合,多重集合)这类容器根据一个元素相关联的key来存储或提取数据元素,存储是以key-value对的形式,按照key的升序(二叉树存储)。

十大容器的共同特点

  • 所有容器都支持拷贝构造 和 拷贝赋值。
  • 相同类型的两个容器之间可以通过==进行相等性判断。
  • 容器存储的为数据的副本这也就意味着存入容器中的对象应支持拷贝构造和拷贝赋值。
  • 通常情况下被存放到容器中的对象应支持无参构造。

1.4 迭代器

  • 顺序迭代器
    一次只能向后或者向前迭代一步,只支持++和–运算。

  • 随机迭代器
    即能一次向后或者向前迭代一步,也可以迭代多步,除了支持++和–,也支持对整数的加减运算。

除了向量和双端队列以及优先队列支持随机迭代器以外,其余容器只支持顺序迭代器

  • 正向迭代器:起始迭代器指向 向量第一个元素位置,终止迭代器指向向量最后一个元素的下一个位置,增操作向容器的尾部移动,减操作 向容器的首部移动。

  • 反向迭代器:起始迭代器指向向量的最后一个元素的位置,终止迭代器指向向量第一个元素的前一个位置,增操作向容器的首部移动,减操作向容器的尾部移动。

四个迭代器类:
iterator / const_iterator / reverse_iterator / const_reverse_iterator

八个迭代器对象:

  • begin() / end()
  • begin()const / end()
  • const rbegin() / rend()
  • rbegin()const / rend()const

二、向量容器

2.1 成员函数

front() / back() / insert() / erase() ——获取头结点数据/尾结点数据;指向位置添加/删除节点

push_back() / pop_back() / empty() / clear()——添加/删除尾结点;判断空/清空向量

size() –向量维护元素个数 ,向量已经存储的数据个数

resize() - 设置向量元素个数 ,

capacity() - 获取向量容量 ,向量最多可以存储的数据个数

reserve() -设置向量的容量
容量反映向量维护多少内存;大小反映已经占了多少内存

2.2 初始化

向量中的元素被存储在一段连续的内存空间中。

向量维护的内存空间会随着新元素的增加而自动增长。

内存空间的连续性不会妨碍向量元素的增加,如果内存空间无法满足新元素的增加,向量会开辟新的足够的连续内存空间,并把原内存空间的数据复制到新的内存空间,释放原内存空间

向量的增加会伴随着内存空间的分配和释放,元素复制和销毁等额外开销。

如果能够在创建向量时,合理预分配一些空间将很大程度上缓解这些额外开销。(reserve())

vector01.cpp

#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
class Student{
public:
	Student(string const& name=""):m_name(name){
		cout << "缺省构造了:" << m_name << "(" << this << ")" << endl;
	}
	Student(Student const& that):m_name(that.m_name){
		cout << "用:" << that.m_name << "(" << &that << ")"
			 << "拷贝构造了:" << m_name << "(" << this << ")" << endl;
	}
	~Student(){
		cout << "析构了:" << m_name << "(" << this << ")" << endl;
	}
private:
	string m_name;
};
int main(){
	
	vector<Student> vs;
	vs.reserve(10);  //p4
	vs.push_back(Student("张三"));//p1
	vs.push_back(Student("李四"));//p2
	vs.push_back(Student("王五"));//p3
	getchar();
	return 0;
}

p1在这里插入图片描述

p2
在这里插入图片描述
副本造副本说明向量内存空间不够,直接向量内存空间搬家。

p3
在这里插入图片描述

p4
在这里插入图片描述

2.3 迭代器的使用

增操作: insert

删操作 : erase

改操作

查操作 : find

排序操作 : sort

三、向量迭代器

增操作: insert

删操作 : erase

改操作

查操作 : find

排序操作 : sort

vector02.cpp

#include <iostream>
#include <vector>
#include <algorithm> // find  /  sort
using namespace std;

class Student{
public:
	Student(string const& name="",int age=0):m_name(name),m_age(age){}
	bool operator==(Student const& that)const{
		return m_name==that.m_name && m_age==that.m_age;
	}
	bool operator<(Student const& that)const{
		return m_age > that.m_age;
	}
private:
	string m_name;
	int m_age;
	friend ostream& operator<<(ostream& os, Student const& that);
};
ostream& operator<<(ostream& os, Student const& that){
	return os << that.m_name << ":" << that.m_age;
}
void print(string const& str, vector<Student>& v){
	cout << str << endl;
	typedef vector<Student>::iterator IT;
	for(IT it=v.begin(); it!=v.end(); ++it)
		cout << *it << ' ';
	cout << endl << "----------------------" << endl;
}
class CMP{
public:
	bool operator()(Student const& a, Student const& b){
		return a < b;
	}
};
int main(){
	vector<Student> vs;
	vs.reserve(10);
	vs.push_back(Student("张飞",22));
	vs.push_back(Student("赵云",20));
	vs.push_back(Student("关羽",25));
	vs.push_back(Student("马超",27));
	vs.push_back(Student("黄忠",44));
	print("添加节点后:", vs);

	vs.insert(vs.begin(),Student("刘备",38));
	print("在迭代器指向的位置添加节点后:", vs);

	vs.erase(vs.begin());
	print("删除迭代器指向的节点后:", vs);

	typedef vector<Student>::iterator IT;
	IT it=vs.begin();
	*it = Student("诸葛亮",18);
	print("更改迭代器指向的节点后:", vs);

	IT fit = find(vs.begin(),vs.end(),Student("赵云",20));//"=="
	if(fit!=vs.end())
		vs.erase(fit);
	print("找到赵云并删除后:", vs);

//	sort(vs.begin(),vs.end());// "<"
	CMP cmp;//比较器
	sort(vs.begin(), vs.end(), cmp);//比较器
	print("排序后:", vs);
	return 0;
}

正向迭代:

typedef vector<Student>::iterator IT;
	for(IT it=v.begin(); it!=v.end(); ++it)
		cout << *it << ' ';

反向迭代

typedef vector<Student>::reverse_iterator rIT;
    for(rIT it = v.rbegin(); it != v.rend(); ++it)
         cout << *it << ' ';

四、双端队列/列表

4.1 双端队列和向量差别

  • 和向量差别就是首尾两端同样都是开放的,因此他同时提供了首尾两端增删元素的接口。

  • 没有提供设置/获取容量的函数,设置和获取容器大小的函数存在。
    deque.cpp

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

class Student{
public:
	Student(string const& name="",int age=0):m_name(name),
					m_age(age){}
	bool operator==(Student const& that)const{
		return m_name==that.m_name && m_age==that.m_age;
	}
	bool operator<(Student const& that)const{
		return m_age > that.m_age;
	}
private:
	string m_name;
	int m_age;
	friend ostream& operator<<(ostream& os, Student const& that);
};
ostream& operator<<(ostream& os, Student const& that){
	return os << that.m_name << ":" << that.m_age;
}
void print(string const& str, deque<Student>& d){
	cout << str << endl;
	//正向迭代
	typedef deque<Student>::iterator IT;
	for(IT it=d.begin(); it!=d.end(); ++it){
		cout << *it << ' ';
	}
	cout << endl << "----------------" << endl;
}
int main(){
	deque<Student> di;
	di.push_front(Student("张飞",22));
	di.push_front(Student("赵云",20));
	di.push_front(Student("马超",26));
	di.push_back(Student("关羽", 28));
	di.push_back(Student("黄忠", 44));
	print("添加节点后:", di);
	typedef deque<Student>::iterator IT;
	di.insert(di.begin(),Student("刘备",50));
	print("在迭代器指向的位置添加节点后:", di);
	di.erase(di.begin());
	print("删除迭代器指向的节点后:", di);

	IT it=di.begin();
	*it = Student("吕布",36);
	print("更改迭代器指向的节点后:", di);

	//"=="
	IT fit = find(di.begin(),di.end(),Student("黄忠",44));
	if(fit!=di.end())
		di.erase(fit);
	print("找到黄忠并删除后:", di);

	sort(di.begin(),di.end());//"<"
	print("排序后:", di);

	return 0;
}

4.2 列表

  • 唯一化
    void unique(void); 将连续重复出现的元素唯一化
  • 排序(都是全局排序)注意sort是成员函数
    void sort(void); 通过 < 比大小
    templatevoid sort(LESS less); 通过比较器比大小

向量排序需要交换元素位置,但链表排序无需交换位置,改变指针指向即可。

  • 拆分:将参数列表中的部分或全部元素剪切到调用列表中
    templatevoid splice( IT pos, list& lst );//全部
    templatevoid splice( IT pos, list& lst, IT del);//一个
    templatevoid splice( IT pos, list& lst, IT begin, IT end);//部分

list.cpp

#include <iostream>
#include <list>
using namespace std;
class CMP{
public:
	bool operator()(int const& a, int const& b){
		return a > b;
	}
};
void print(string const& str, list<int>& l){
	cout << str << endl;
	typedef list<int>::iterator IT;
	for(IT it=l.begin(); it!=l.end(); ++it)
		cout << *it << ' ';
	cout << endl << "---------------" << endl;
}
int main(){
	list<int> ls;
	for(int i=0; i<5; i++)
		ls.push_front(10+i);
	for(int i=0; i<5; i++)
		ls.push_back(10-i);
	print("添加节点后:", ls);
	ls.unique();
	print("唯一化后:", ls);

//	ls.sort();
	CMP cmp;//比较器
	ls.sort(cmp);
	print("排序后:", ls);

	list<int> lst;
	lst.push_back(1000);
	lst.push_back(2000);
	lst.push_back(3000);
	lst.push_back(4000);
	
//	ls.splice(ls.begin(),lst);
//	ls.splice(ls.begin(),lst,lst.begin());
	ls.splice(ls.begin(),lst,++lst.begin(),--lst.end());
	print("ls:", ls);
	print("lst:", lst);
	return 0;
}

五、适配器容器

5.1 栈

  • 定义形式
    stack<元素类型,[底层容器类型]> 堆栈对象(构造实参表)

  • 底层容器:vector / deque(默认) / list / 自己实现的容器作为栈的底层容器

  • 成员函数

    push ->push_back
    pop ->pop_back
    top -> back
    size -> size
    empty -> empty
    clear -> clear

  • 栈的底层实现

tempalate<class T,class D=deque<T>> class stack{
	public:
		void push(T data)	{		m_d.push_back(data);	 }
		void pop()		{		m_d.pop_back();	 }
		……
	private:
		D m_d; //deque<int> m_d//vector<int> m_d
	};

stack s; 或 stack<int,vector> s; 或 stack<int,list> s;

stack.cpp

nclude <iostream>
#include <stack>
#include <vector>
#include <deque>
#include <list>
using namespace std;

int main(){
	stack<int,deque<int> > s;//若不写deque?vector,默认也是deque
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);
	s.push(5);
	s.push(6);
	while(!s.empty()){
		cout << s.top() << endl;
		s.pop();
	}
	return 0;
}

5.2 队列

  • 定义形式
    queue<元素类型,[底层容器类型]> 队列对象(构造实参表)

  • 底层容器:deque(默认) / list / vector不可以(向量不支持头部删除功能)

  • 成员函数
    push ->push_back
    pop ->pop_front(向量没有这个方法 )
    back - > back
    front -> front
    size -> size / empty -> empty / clear -> clear

  • 队列的底层实现
    tempalate<class T,class D=deque> class queue{
    public:
    void push(T data) { m_d.push_back(data); }
    void pop() { m_d.pop_front(); }
    ……
    private:
    D m_d; //
    };

queue s; 或 queue<int,vector> s(这个方法是错误的); 或 queue<int,list> s;

queue.cpp

#include <iostream>
#include <queue>
#include <vector>
#include <deque>
#include <list>
using namespace std;

int main(){
	queue<int,deque<int> > s;
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);
	s.push(5);
	s.push(6);
	while(!s.empty()){
		cout << s.front() << endl;
		s.pop();
	}
	return 0;
}

5.3 优先队列

  • 定义形式:
    priority_queue<元素类型,【底层容器类型】,【比较器类型】>
    优先队列对象(构造实参表)
  • 底层容器:deque(默认) /vector
    (支持随机迭代,不能list)
  • 注意事项:
    优者先出,默认以大者为优也可以通过比较器定制(比- 较器必须是类),
    如果没有“比较器”默认内部使用<运算符

    并不是出队时挑,而且进队列时就保证有序
  • 成员函数
    push /pop / top / empty / size / clear

priority.cpp

#include <iostream>
#include <queue>
#include <vector>
#include <deque>
#include <list>
using namespace std;
class CMP{
public:
	bool operator()(int const& a, int const& b){
		return a > b;
	}
};
int main(){
	priority_queue<int,deque<int>,CMP> pq;
	pq.push(3);
	pq.push(8);
	pq.push(4);
	pq.push(9);
	pq.push(5);
	pq.push(7);
	while(!pq.empty()){
		cout << pq.top() << endl;
		pq.pop();
	}
	return 0;
}

六、关联容器

6.1 映射

头文件:map

  • 定义形式: map<键类型,值类型> 映射对象;

  • 逻辑模型:–对应模型 键(信息索引)值(信息内容)对,主要用于信息检索,性能可以达到对数级(O(logN)),类似二分法。

  • 物理模型:平衡有序二叉树又名红黑树。

  • 在这里插入图片描述
    红黑树

在这里插入图片描述

此时5以下的节点超过2层,以4为中心,顺时针转,即变为:

在这里插入图片描述在这里插入图片描述
此时又不符合平衡,以3为中心顺时针旋转:

在这里插入图片描述

树形结构的最大好处:检索速度快

  • 键必须唯一。

  • 迭代过程实际上是关于键的中序遍历(L D R),键的升序。

  • 存储单位是由键和值组成的pair。
    template<class FIRST,class SECOND>class pair{
    public:
    pair(FIRST const& f, SECOND const& s) : first(f),second(s){}
    FIRST first; //键
    SECOND second;//值
    }

在这里插入图片描述
映射的迭代器相当于指向pair对象的指针。

在这里插入图片描述

  • 映射中的键是只读的。
  • 检索性能好(一砍砍一半)构建和修改性能较差 ,适用于结构稳定,但是需要频繁检索的操作。
  • 支持“下标”运算,用键作为下标,得到对应的值的引用,如果所给出的键不存在,增加一个节点,返回其值的引用。
  • 成员函数
    insert( pair<FIRST,SECOND>(键,值) )
    insert( make_pair(键,值))
    迭代器 = find(键);
    失败返回终止迭代(并非全局函数而是 成员函数)
#include <iostream>
#include <map>
using namespace std;
class Candidate{
public:
	Candidate(string name=""):m_name(name),m_vote(0){}
	string m_name;
	int m_vote;
};
void print(map<char,Candidate>& m){
	typedef map<char,Candidate>::iterator IT;
	for(IT it=m.begin(); it!=m.end(); ++it){
		cout << "(" << (*it).first << ")" << 
				(*it).second.m_name << ' ';
	}
	cout << endl;
}
int main(){
	map<char,Candidate> m;
	m.insert(pair<char,Candidate>('A',Candidate("张飞")));
	m.insert(make_pair('B',Candidate("关羽")));
	//映射容器支持下标操作
	m['C'] = Candidate("赵云");
	m['D'] = Candidate("马超");
	m['E'] = Candidate("黄忠");
	typedef map<char,Candidate>::iterator IT;
	for(int i=0; i<10; i++){
		print(m);
		char ch;
		cin >> ch;
		IT fit = m.find(ch);
		if(fit==m.end()){
			cout << "废票" << endl;
			continue;
		}
		++(*fit).second.m_vote;
	}
	for(IT it=m.begin(); it!=m.end(); ++it){
		cout << (*it).second.m_name << ":" 
		     << (*it).second.m_vote << endl;
	}
	return 0;
}

6.2 多重映射

允许键重复的映射,表示一对多的逻辑关系,不支持下标运算符。
比如一个学生,既有期中成绩又有期末成绩。

multiMap.cpp

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

int main(){
	multimap<string,int> m;
	m.insert(make_pair("张飞",80));
	m.insert(make_pair("赵云",70));
	m.insert(make_pair("关羽",60));
	m.insert(make_pair("张飞",50));
	m.insert(make_pair("赵云",40));
	m.insert(make_pair("关羽",30));
	typedef multimap<string,int>::iterator IT;
	for(IT it=m.begin(); it!=m.end(); ++it){
		cout << (*it).first << ":" << (*it).second << ' ';
	}
	cout << endl;
	return 0;
}

6.3 集合

  • 没有值只有键的映射

  • 与向量等基本容器相比最大优势就是 排重(排除重复元素)。

内部结构为红黑树:检索信息快。

set.cpp

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

int main(){
	set<int> s;
	s.insert(1);
	s.insert(2);
	s.insert(3);
	s.insert(1);
	s.insert(2);
	s.insert(3);
	cout << "节点个数:" << s.size() << endl;
	typedef set<int>::iterator IT;
	for(IT it=s.begin(); it!=s.end(); ++it)
		cout << (*it) << ' ';
	cout << endl;
	return 0;
}

在这里插入图片描述

6.4 多重集合

  • 没有值只有键的多重映射。

其内部结构仍然为红黑树:检索效率高于普通容器。

multiSet.cpp

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

int main(){
	multiset<int> s;
	s.insert(1);
	s.insert(2);
	s.insert(3);
	s.insert(1);
	s.insert(2);
	s.insert(3);
	cout << "节点个数:" << s.size() << endl;
	typedef multiset<int>::iterator IT;
	for(IT it=s.begin(); it!=s.end(); ++it)
		cout << (*it) << ' ';
	cout << endl;
	return 0;
}

在这里插入图片描述

七、总结

主要四大容器:向量、双端队列、列表、映射。

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

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

相关文章

软件生命周期阶段有几个?常见软件生命周期模型有哪些?

软件生命周期阶段及常见的软件生命周期模型&#xff0c;软件生命周期是指一个计算机软件从功能确定、设计&#xff0c;到开发 成功投入使用&#xff0c;并在使用中不断地修改、增补和完善&#xff0c;直到停止该软件的使用的全过程。  生命周期从收到应用软件开始算起&#x…

springboot 多模块项目构建【创建√ + 启动√ 】

一、多模块项目构建 1. 先建立父级目录demo-parent 2. 把父级目录src删除&#xff0c;再建立子级模块 3. 建立子级模块model,dao,service,common.utils等相同步骤 4. 建立启动模块boot, 创建Spring Boot 启动类 package com.example;import org.springframework.boot.SpringAp…

http服务转https服务(Nginx 服务器 SSL 证书安装部署)

安装的服务一直使用的是http&#xff0c;结果有客户要求必需使用https,下面是整理的步骤1、证书下载&#xff1a;&#xff08;要用域名申请的账号登录&#xff09;域名所在服务商一般都可以下载免费证书&#xff0c;我们用的域名是腾讯云的&#xff0c;所以在腾讯云上申请了免费…

高通开发系列 - gpio模拟输出PWM或者CLK时钟

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 问题背景平台信息GPIO输出CLKdts添加节点修改内核gcc时钟配置驱动文件编译运行gpio模拟PWM输出CLKdts中的配置GPIO模拟PWM驱动文件编译…

MSF信息收集

Nmap扫描 db_nmap -sV 192.168.1.0/24Auxiliary 扫描模块 ● RHOSTS表示 192.168.1.20-192.168.1.30 、 192.168.1.0/24,192.168.11.0/24&#xff08;扫描两个网段&#xff09; file:/root/host.txt (将需要扫描的主机访问文本中)● search arp use auxiliary/scanner/d…

网站收录查询方法,网站收录减少的原因

网站收录就是与互联网用户共享网址&#xff0c;网站收录前提是网站首页提交给搜索引擎&#xff0c;蜘蛛才会光顾&#xff0c;每次抓取网页时都会向索引中添加并更新新的网站&#xff0c;站长只需提供顶层网页即可&#xff0c;不必提交各个单独的网页。抓取工具能够找到其他网页…

华为matebook X 笔记本没开什么程序,有时经常慢卡

环境&#xff1a; 华为matebook X CPU &#xff1a;英特尔4核8线程10代 i5 内存&#xff1a;海力士16G 固态硬盘500G 问题描述&#xff1a; 华为matebook X 没开什么程序&#xff0c;经常慢卡&#xff0c;平时就是打开钉钉&#xff0c;处理处理文档&#xff0c;之前优化过…

模板题---1.5(单调栈,单调队列,kmp,manachar)

这里写目录标题1.单调栈2.单调队列3.kmp算法4.manachar算法这里记录几个基本的数据结构算法1.单调栈 要点&#xff1a; 数据结构是栈栈要维护单调性 这就是单调栈的基本定义 举个例子: &#xff08;栈底&#xff09;1 3 5 7 &#xff08;栈顶&#xff09; <-------这就是…

行为型模式 - 备忘录模式Memento

学习而来&#xff0c;代码是自己敲的。也有些自己的理解在里边&#xff0c;有问题希望大家指出。 模式的定义与特点 在备忘录模式&#xff08;Memento Pattern&#xff09;下&#xff0c;为的是在不破坏封装性的前提下&#xff0c;捕获一个对象的内部状态&#xff0c;并在该对象…

【C++ Primer】阅读笔记(2):const | constexpr | 类型别名 |auto

目录 简介const指针顶层const与底层const常量表达式constexpr类型别名auto参考结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计算机专业,获得过…

CTF中的PHP特性函数(下)

前言 上篇文章讲的进阶一些的PHP特性不知道大家吸收的怎么样了&#xff0c;今天作为本PHP特性函数的最后一篇&#xff0c;我也会重点介绍一些有趣的PHP特性以及利用方法&#xff0c;下面开始我们今天的内容分享。 parse_str parse_str()这个函数会把查询字符串解析到变量中。…

二叉树——链式存储

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;数据结构——二叉树 &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;上期讲了…

LinkedList与链表(一)(非循环单向链表)

ArrayList的缺陷通过ArrayList上节课的学习&#xff0c;我们了解到如果ArrayList要删除或插入一个元素&#xff0c;后面的元素都要进行移动&#xff0c;时间复杂度为O(n),效率比较低&#xff0c;因此ArrayList不适合做任意位置的插入和删除操作比较多的场景。因此java集合又引入…

Python if __name__ == “__main__“ 用法

文章目录1 前言2 原理3 __name__变量的作用参考1 前言 在很多Python程序中&#xff0c;我们都会遇到if __name__ "__main__"的情况&#xff0c;却不知道为何要这样做 在很多编程语言中&#xff0c;如C、Java等&#xff0c;都需要程序的入口&#xff0c;一般都是ma…

MySql锁机制(全网最全、最详细、最清晰)

1、MySql锁机制 锁机制的作用&#xff1a; 解决因为资源共享&#xff0c;而造成的并发问题。 没有锁机制时&#xff1a; 例如一号用户和二号用户都要去买同一件商品&#xff08;假如这件商品是一件衣服&#xff09;&#xff0c;一号用户手速稍微快了一些&#xff0c;于是就…

从事软件测试需要学自动化么

相信许多对软件测试有过一点了解的人&#xff0c;对自动化都不会感到陌生。我们常常会听到一定软件测试人员一定要学自动化的说法&#xff0c;那么很多人都会有这样的疑问&#xff0c;从事软件测试为什么要学自动化&#xff1f;事实上&#xff0c;如今只会功能测试的从业者往往…

光波导成为AR眼镜迭代新趋势,二维扩瞳几何光波导潜力彰显

关注AR眼镜的朋友可能都会发现&#xff0c;近期新品迭代的一个趋势是持续在小型化、轻量化方向演进。与一年前光学方案主要以BirdBath不同的是&#xff0c;消费级AR眼镜正快速向光波导方案探索和转变。这一点在最近发布的众多新品AR眼镜中就能明显的感受到&#xff0c;以视享G5…

堆排序 TopK 优先级队列的部分源码 JAVA对象的比较

一.堆排序:我们该如何借助堆来对数组的内容来进行排序呢&#xff1f; 假设我们现在有一个数组&#xff0c;要求从小到大进行排序&#xff0c;我们是需要进行建立一个大堆还是建立一个小堆呢&#xff1f; 1)我的第一步的思路就是建立一个小堆&#xff0c;因为每一次堆顶上面的元…

MGRE和ospf的综合运用

目录实验需求知识点实验过程一&#xff0c;在R1 R2 R3中的MGRE搭建二&#xff0c;在R1 R4 R5中的MGRE搭建三&#xff0c;整个内网的ospf协议实验需求 一 题目要求 1&#xff0c;R6为ISP代表运营商&#xff0c;只能配置ip地址&#xff0c;R1-R5环回 代表私有网段 2&#xff0c…

【Linux】顶级编辑器Vim的基本使用及配置

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;Linux 文章目录一、前言二、vim基本概念三、vim 基本操作1、模式切换2、命令模式3、插入模式4、底行模式四…