⭐️STL⭐️之string和vector全解,❤️算法必备❤️<上>

举报
秋名山码民 发表于 2022/03/12 12:26:44 2022/03/12
【摘要】 @TOC 前言码神本来是想一次性就把STL,都讲完的,但是上次爆肝5w字后发现效果并不好,所以就把STL拆分成了,三个小部分来讲解,感觉还是比较重要的,算法也在继续,但是我感觉干算法以前还是要讲一下——STL,所以发车了,去做自己喜欢的事情吧!🎉欢迎关注🔎点赞👍收藏⭐️留言📝 STL的组成何为STL,在书中是这样描述的:C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提...

@TOC


前言

码神本来是想一次性就把STL,都讲完的,但是上次爆肝5w字后发现效果并不好,所以就把STL拆分成了,三个小部分来讲解,感觉还是比较重要的,算法也在继续,但是我感觉干算法以前还是要讲一下——STL,所以发车了,去做自己喜欢的事情吧!
🎉欢迎关注🔎点赞👍收藏⭐️留言📝

STL的组成

何为STL,在书中是这样描述的:C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了💕通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。
如果说他的存在是为了什么的话,我想应该是提高了可重复利用性。
核心:

  • 容器
  • 迭代器
  • 算法

几个关键词

先来说几个比较重要的关键词
push_back( ) 成员函数在向量的末尾插入值,如果有必要会扩展向量的大小。
size( ) 函数显示向量的大小。
begin( ) 函数返回一个指向向量开头的迭代器。
end( ) 函数返回一个指向向量末尾的迭代器。

下面我们上,👌将string和vector放到一起是因为:
在 STL 中,拥有 capacity 属性的容器只有 vector 和 string。

针对 capacity 这个属性,STL 中的其他容器,如 list map set deque,由于这些容器的内存是散列分布的,因此不会发生类似 realloc() 的调用情况,因此我们可以认为 capacity 属性针对这些容器是没有意义的,因此设计时这些容器没有该属性。

string

string有点像字符串,如果在c中我问你字符串的本质是什么?应该回答是指针,但是如果说string的本质是什么,那么就是类。

string和char指针的基本操作:

#include<string>
#include<iostream>
using namespace std;
void test01()
{
	string s1;
	const char *str = "aaa0";
	string s2(str);
	cout << s1<<endl<<s2;

	//调用拷贝构造函数
	string s3(s2);

	//
	string s4(10, 'a');
	cout << s4;
}
int main()
{
	test01();
	return 0;
}

string的基本赋值操作

#include<string>
#include<iostream>
using namespace std;
void test01()
{
	string s1;
	s1 = "hello C++";
	string s2;
	s2 = s1;
	string s3;
	s3 = 'a';
	string s4;
	s4.assign("hello c++");
	string s5;
	s5.assign("hello c++", 5);//前5个赋值给s5
	cout << s5 << endl;;

	string s6;
	s6.assign(s5);
	cout << s6 << endl;

	string s7;
	s7.assign(5, 'x');//5个x
	cout << s7 << endl;
}
int main()
{
	test01();
	return 0;
}

下面再来说几个string中常用的函数

先来第一个string的比较

//用字符ascll码进行比较
//=返回0
//>返回1,<返回-1
#include<string>
#include<iostream>
using namespace std;
void test01()
{
	string str1="hello";
	string str2 = "hello";
	if (str1.compare(str1)==0)
	{
		cout << "=";
	}
	else if (str1.compare(str2) > 0)
	{
		cout << ">";
	}
	else if (str1.compare(str2) < 0)
	{
		cout << "<";
	}
}
int main()
{
	test01();
	return 0;
	//在实际开发中主要是用来比较是否等于
}

下一个是string的查找

//若有重复字符则rfind()返回的是逆向查找到的字符在正向的位置
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
	string str1="jskkkskk";
	int a=str1.find("js");
	int b = str1.rfind("js");
	//如果找不到,返回-1
	cout << a<<" "<<b<<endl;

}
//替换
void test02()
{
	string str2 = "jkjjjssss";
	str2.replace(1, 3, "1111");
	//从1号开始,替换3个为4个1
	cout << str2;

}
int main()
{
	test01();
	test02();
	return 0;
}

查找的前提是存取吧,那么看存取

//at,size
#include<iostream>
#include<string>
using namespace std;
void test01()
{
	string str1 = "hello";
	for (int i = 0; i < str1.size(); i++)
	{
		cout << str1.at(i) << endl;
	}
	
	//修改
	str1.at(1) = 'a';
	str1[0] = 'a';
	for (int i = 0; i < str1.size(); i++)
	{
		cout << str1[i];
	}
}
int main()
{
	test01();
	return 0;
}

存进去,总要修改,再来一个

#include<iostream>
#include<string>
using namespace std;
void test01()
{
	string str1 = "hello";
	str1.insert(1, "111");
	//在第一个元素前插入
	cout << str1 << endl;
	str1.erase(1, 3);
	//erase是橡皮的意思,删除
	//表示从1开始删除3个
	cout << str1 << endl;

}
int main()
{
	test01();
	return 0;
}

下面是获取和拼接

#include<iostream>
#include<string>
using namespace std;
void test01()
{
	string str1;
	str1 += "ye";
	string str2;
	str2 = "jjff";
	str1 += str2;

	string str3="I";
	str3.append(" Love");
	str3.append("game abcde", 4);
	str3.append(str2, 2, 1);//从str2中开始的2,接1,拼接
	cout << str3;

}
int main()
{
	test01();
	return 0;
}

最后一个,string的截取

#include<iostream>
#include<string>
using namespace std;
void test01()
{
	string str1 = "javbjjj";
	string str2 = str1.substr(1, 2);
	cout << str2 << endl;
}
//来个邮箱吧
void test02()
{
	string str3 = "masheng@qq.com";
	int num = str3.find('@');
	string str4 = str3.substr(0, num);
	cout << str4;
}
int main()
{
	test01();
	test02();
	return 0;
}

vector

首先我们会发现vector像数组,那么它和数组最大 的区别是什么?
👍vector与数组最大区别就是动态扩展,不是续写,而是找一块更大的空间,拷贝原有的数据,释放原有的空间
他的构造形式有一下几种,一般没有具体的好坏,凭借心情使用

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> &v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	vector<int> v1;//默认构造
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	print(v1);

	vector<int> v2(v1.begin(),v1.end());
	print(v2);

	vector<int> v3(10, 100);
	print(v3);

	vector<int> v4(v3);
	print(v4);
}
int main()
{
	test01();
	return 0;
}

下面是vector数据的存取,比较简单,相当于读入数据

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
}
void test01()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	v1.at(0) = 99;
	v1[0] = 98;
	print(v1);
}
int main()
{
	test01();
	return 0;
}

其中iterator是一个迭代器,这里我们存入了int型的变量,当然也可以存入其他的变量,例如,存入一个结构体

#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Person
{
public:
	Person(string name, int age)
	{
		m_name = name;
		m_age = age;
	}
public:
	string m_name;
	int m_age;
};
void test01()
{
	vector<Person> v;
	//创建数据
	Person p1("aaa", 10);
	Person p2("bbb", 20);

	v.push_back(p1);
	v.push_back(p2);

	for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << it->m_name << it->m_age << endl;
		cout << (*it).m_name << (*it).m_age << endl;
	}
}
void test02()
{
	vector<Person> v;
	//创建数据
	Person p1("aaa", 10);
	Person p2("bbb", 20);
	for (vector<Person*>::iterator it = v.begin(); it !=  v.end(); it++)
	{
		Person *p = *it;
		cout << p->m_name << (*it)->m_age << endl;
	}
}
int main()
{
	test01();
	return 0;
}

C++ STL 之 vector 的 💖capacity 和 size 属性💖区别
size 是当前 vector 容器真实占用的大小,也就是容器当前拥有多少个容器。
capacity 是指在发生 realloc 前能允许的最大元素数,即预分配的内存空间。

当然,这两个属性分别对应两个方法:resize() 和 reserve()。
使用 resize() 容器内的对象内存空间是真正存在的。
使用 reserve() 仅仅只是修改了 capacity 的值,容器内的对象并没有真实的内存空间(空间是"野"的)。
此时切记使用 [] 操作符访问容器内的对象,很可能出现数组越界的问题。

下面用代码来看一下

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> &v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
		
	}
	cout << endl;
}
void test01()
{
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	if (v1.empty())
		cout << "weikong";//为真代表为空
	else
	{
		cout << "不为空";
		cout << v1.capacity()<<" ";//动态扩展到13
		cout << v1.size()<<" ";//大小
	}
	//重新指定大小
	v1.resize(15);//默认不够的都补为0
	v1.resize(15, 100);
	//自定义
	v1.resize(5);//超出的会删掉
	print(v1);
}
int main()
{
	test01();
	return 0;
}

vector的插入和删除所用的函数与string,大同小异
/*
push_back
pop_back
erase
clear
intsert
*/

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> v)
{
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
	{
		cout << *it << " ";
	}
}
void test01()
{
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(20);//尾插

	v1.pop_back();//尾删

	//插入
	v1.insert(v1.begin(), 100);
	v1.insert(v1.begin(), 2, 20);
	//删除,参数也是迭代器
	v1.erase(v1.begin());
	v1.erase(v1.begin(), v1.end());

	//清空
	v1.clear();
	print(v1);
}
int main()
{
	test01();
	return 0;
}

最后

🎉欢迎关注🔎点赞👍收藏⭐️留言📝
如果喜欢stl的话,未来3天更新完成

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。