C++蓝桥算法前置必备(二)

了解STL (Standard Template Library 标准模板库)
STL的三个主要组件
容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
算法(algorithm):各种常用的算法,如sort、find、copy、for_each等
迭代器:用来遍历容器中的元素,且迭代器使用非常类似于指针

一、vector容器

可以理解为数组STL中最常用的容器为Vector,可以理解为数组。
和普通数组不同之处在于数组是静态空间,而vector可以动态拓展。
同时,vevtor并不是在原空间之后许接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间,释放原空间。

默认构造&容器复制

	vector<int> v1; 
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	两种复制方式
	vector<int> v2;
	v2.assign(v1.begin(), v1.end());
	
	vector<int> v3(v1);

函数原型

插入和删除
  - push_back()   	向容器中放数据
  - pop_back()	删除最后一个元素
  - v1.insert(v1.begin(), 100);    在v1.begin()的位置插入100
  - insert(v1.begin(), int count = 10,ele = 20);//迭代器指向位置pos插入10个元素20
  - erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
  - erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
  - erase(elem); //删除容器中值为elem的元素。
  - clear(); //删除容器中所有元素
容量和大小
  - enpty()	判断容器是否为空
  - capacity()	容器的容量
  - size()	返回容器中元素的个数
  - resize( int 40)	重新指定容器的长度为50,若容器变长,则以默认值填充新位置;如果容器变短,则末尾超出容器长度的元素被删除。
  - resize( int 50, int 10)	  //重新指定容器的长度为50,若容器变长,则以10值填充新位置。
数据存取
  - at(int idx);  //返回索引idx所指的数据
  - operator[];  //返回索引idx所指的数据
  - front();  //返回容器中第一个数据元素
  - back(); //返回容器中最后一个数据元素
- 互换容器
  - v1.swap(v2)	实现两个容器内元素进行互换
预留空间
  reserve( int len)	容器预留len个元素长度,预留位置不初始化,元素不可以访问

字符串指定个数输入

  • 第一种方法
vector<int>v1(3);
	
	for ( int &elem : v1) {
		cin >> elem;
	}
  • 第二种方法
vector<int>v1;
	
	int elem;
	for ( int i = 0; i < 4; i++) {
		cin >> elem;
		v1.push_back(elem);
	}

遍历写法

v.begin()返回迭代器,这个迭代器指向容器中第一个数据
v.end()返回迭代器,这个迭代器指向容器元素的最后一个元素的下一个位置
vector::iterator 拿到vector这种容器的迭代器类型

当用到for_each函数时,注意添加上#include 头文件

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

void test01() {
	vector<int>::iterator pBegin = v.begin();
	vector<int>::iterator pEnd = v.end();
	//第一种遍历方式:
	while (pBegin != pEnd) {
		cout << *pBegin << endl;
		pBegin++;
	}

	//第二种遍历方式:
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
		cout << *it << endl;
	}
	cout << endl;

	//第三种遍历方式:
	//使用STL提供标准遍历算法  头文件 algorithm
	for_each(pBegin, pEnd, MyPrint);
	for_each(v.begin(), v.end(), MyPrint);
}

deque容器

  • 双端数组,可以对头端进行插入和删除操作

默认构造&容器复制

	deque<int> d1; 
	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}

	两种复制方式
	deque<int> d2;
	d2.assign(d1.begin(), d1.end());
	
	deque<int> d3(d2);

函数原型

在原有的vector容器中增加了以下函数:
注意: deque容器没有capacity的概念,并且在pop_back或者pop_front中括号中是不用给定参数的。 因为vector容器并没有指定是否是最后一个元素,所以需要在erase中指定删除的下标。

  • push_front(10) 在头部插入数据10
  • pop_front() 删除容器第一个数据

排序算法

sort算法非常实用,使用时包含头文件 algorithm即可

sort(d.begin(), d.end());

二、string容器

string本质上是一个类,类内部封装了char*管理这个字符串。

  • 字符串赋值
//头文件
#include <string>
//	三种方式
	str1 = "hello world";
	string str2 = str1;
	str4.assign("hello c++");
}
  • 字符串的拼接的两种方式
	string str1 = "我";
	str1 += "爱玩游戏";

	string str3 = "I";
	str3.append(" love ");
  • string的查找和替换
str2.find("ao") != -1
str2.rfind("ao") != -1  从右向左查,并返回元素的起始位置
	
	
	str2.replace(0, 5, str1);
	cout << str2 << endl; 
}

一个例子:
查找字符串中存在多少待查的子串

	string mainString = "abababcababcabab";
    string subString = "ab";

    int pos = mainString.find(subString); // 查找子串的第一次出现位置

    int count = 0;
    while (pos != string::npos) {
        // 找到一个子串后,继续在剩余部分查找
        count++;
        //find( 待查找的字符串,  找到的字符的下一个位置)
        pos = mainString.find(subString, pos + subString.length());
    }

如果 subString 存在于 mainString 中,find 函数返回子串在字符串中的位置,否则返回 string::npos,用于表示未找到。

  • 字符串比较
	string s1 = "hello";
	string s2 = "aello";
	int ret = s1.compare(s2);
  • 字符串修改
	str[0] = 'x';
	str.at(1) = 'x';
  • 字符串的插入和删除
    erase函数的两个参数 第一个是开始的位置,第二个是从该位置开始 的几个元素
//字符串插入和删除
void test01()
{
	string str = "hello";
	str.insert(1, "111");
	cout << str << endl;

	str.erase(1, 3);  //从1号位置开始3个字符
	cout << str << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}
  • string子串

string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字符组成的字符串

	string str = "abcdefg";
	string subStr = str.substr(1, 3);
	cout << "subStr = " << subStr << endl;

	string email = "hello@sina.com";
	int pos = email.find("@");
	string username = email.substr(0, pos);
	cout << "username: " << username << endl;

三、stack容器

stack是一种先进后出的数据结构,又叫栈。

#include <stack>
stack<int> s;
  • 数据存取:
    push(elem); //向栈顶添加元素
    pop(); //从栈顶移除第一个元素
    top(); //返回栈顶元素
  • 大小操作:
    empty(); //判断堆栈是否为空
    size(); //返回栈的大小

栈不支持直接在定义的时候指定大小,所以可以采用for循环的形式将元素压入栈,并且通过判断栈是否为空遍历栈中的元素(逆序输出)

	stack<int> v1;
	int elem;
	for ( int i = 0; i < 4; i++) {
		cin >> elem;
		v1.push(elem);
	}
	
	
	while ( !v1.empty()) {
		cout << v1.top() << " ";
		v1.pop();
	}
	
	cout << endl;

四、queue容器

queue是一种先进先出的数据结构,又叫队列。

  • 数据存取:
    push(elem); //往队尾添加元素
    pop(); //从队头移除第一个元素
    back(); //返回最后一个元素
    front(); //返回第一个元素

  • 大小操作:
    empty(); //判断堆栈是否为空
    size(); //返回队的大小

queue<int> v1;
	int elem;
	for ( int i = 0; i < 4; i++) {
		cin >> elem;
		v1.push(elem);
		cout << v1.back() << " ";
	}
	cout << endl << "大小:" << v1.size() << endl;
	
	while ( !v1.empty()) {
		cout << v1.front() << " ";
		v1.pop();
	}
	
	cout << endl;

五、list容器

和deque一定的不同

  • 在指定位置插入元素
**auto it = v1.begin();
    advance(it, 2);
    v1.insert(it, 35);**
  • 排序
    因为list不支持随机访问迭代器,而sort函数通常期望能够直接访问容器中的元素。所以我们采用list自带的sort函数。
v1.sort();
  • 移除元素
    移除的为删除容器中所有与11匹配的元素。
v1.remove(11);
  • 翻转链表
v1.reverse();

六、set/multiset容器

所有元素都会在插入时自动被排序其底层使用的是二叉树实现

set和multiset区别:
  set不允许容器中有重复的元素
  multiset允许容器中有重复的元素
  **set插入数据的同时会返回插入结果,表示插入是否成功**

注意: 使用multiset之间在创建的时候写成下面的形式,不是修改头文件,头文件依旧是#include

multiset<int>v1;

set构造和赋值

set容器插入数据时用insert

v1.insert(elem);

基本函数

  • insert
  • erase
  • clear
  • find
  • count
  • size
  • empty
  • swap

set查找与统计

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

  • count(key); //统计key的元素个数 但是对于set而言除了0就是1

  • set不支持指定位置删除元素,但是可以采用下面的方法

	auto it = v1.begin();
	advance(it, 2);
	v1.erase(it);
  • find函数的应用
	set<int>::iterator pos = v1.find(13);
	if (pos != v1.end()) {
		cout << "找到了元素" << endl; 
	} else {
		cout << "未找到元素" << endl; 
	}

pair对组创建

成对出现的数据,利用对组可以返回两个数据

两种创建方式:

pair<type, type> p ( value1, value2 );
pair<type, type> p = make_pair( value1, value2 );

利用仿函数改变排列规则

使用仿函数要在创建的时候就指定排列规则

class MyCompare 
{
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};

七、map/ multimap容器

特点:
  - map中所有元素都是pair
  - pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  - 所有元素都会根据元素的键值自动排序
  - 其底层也是使用二叉树实现的。
  - 可以根据key值快速找到value值
  - 很多功能同set容器
  • map的创建
map<int,int>m; //默认构造
  • map的插入方式
m.insert(make_pair(2, 20));
  • 利用防函数排序
class MyCompare {
public:
	bool operator()(int v1, int v2) {
		return v1 > v2;
	}
};

map<int, int, MyCompare> m;
  • map的遍历输出
for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "key:" << it->first << " value:" << it->second << endl;
	}
  • 44
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
鉴于提供的内容是一段包含三个不同的Java程序的代码,我无法提供一个完整的答案来回答你的问题。但是,我可以为你提供一些信息。 根据引用和引用的内容,这两个程序都涉及到动态规划的算法。引用中的程序解决了一个关于序列的最长递增子序列的问题,而引用中的程序解决了一个关于背包问题的维动态规划的问题。 对于引用中的内容,它是一个程序解决的是一个最长上升子序列的问题。 根据提供的代码,这些程序可能是用来解决一些蓝桥杯竞赛的题目。然而,我无法提供更多关于具体问题的信息。 如果你需要帮助解决特定的问题,我建议你仔细阅读每个程序的代码并理解它们的功能,然后根据需要进行相应的修改。如果你有关于动态规划或蓝桥杯竞赛的更具体的问题,我会很愿意帮助你。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [蓝桥杯AcWing学习笔记 3-2简单DP的学习(附相关蓝桥真题:地宫取宝、波动数列)(Java)](https://blog.csdn.net/weixin_53407527/article/details/123122245)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扬子期

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值