【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题

这篇具有很好参考价值的文章主要介绍了【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

更多算法例题链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题)

C++ 内置模板(STL)

迭代器讲解

什么是迭代器(iterator)

迭代器(iterator)的定义:迭代器是一种检查容器内元素并遍历元素的数据类型。
迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。
容器vectorstring有迭代器类型同时拥有返回迭代器的成员。

如:容器有成员 .begin() .end(),其中 .begin() 成员复制返回指向第一个元素的迭代器,即指向第一个元素的“地址”,而 .end() 成员返回指向容器尾元素的下一个位置的迭代器.
.begin() 指向的是第一个合法元素的位置,.end() 指向是容器后第一个不合法元素的地址。

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

int main()
{
    vector<int> nums;
    nums.push_back(1);
    nums.push_back(2);
    nums.push_back(4);
    nums.push_back(8);
    nums.push_back(16);

    vector<string> fruits;
    fruits.push_back("orange");
    fruits.push_back("apple");
    fruits.push_back("raspberry");

    vector<char> empty;

    // 求和 vector nums 中的所有整数(若存在),仅打印结果。
    int sum = 0;
    for (vector<int>::iterator it = nums.begin(); it != nums.end(); ++it)
        sum += *it;
    cout << "Sum of nums: " << sum << "\n";

    // 打印 vector fruits 中的首个 fruis ,不检查是否有一个。
    if (!fruits.empty())
        cout << "First fruit: " << fruits.front() << "\n";

    if (empty.empty())
        cout << "vector 'empty' is indeed empty.\n";
    
    return 0;
}

/*输出:
Sum of nums: 31
First fruit: orange
vector 'empty' is indeed empty
*/

相应的还有容器反向迭代器成员 .rbegin() .rend().rbegin() 返回容器的元素前最后一个不合法的地址,rend() 返回容器的最后一个合法地址。
【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题,算法,c++,开发语言,数据结构

容器迭代器的使用

每种容器类型都定义了自己的迭代器类型:
vector:vector<int>::iterator iter;//定义一个名为iter的变量

数据类型是由vector<int>定义的 iterator 类型。简单说就是容器类定义了自己的 iterator 类型,用于访问容器内的元素。每个容器定义了一种名为iterator的类型,这种类型支持迭代器的各种行为。

容器(vector)(线性表的使用)

Vector 容器(类:线性表中有 vectorlist,两者作用比较相似。vector 的主要作用就是可变长度的数组,就把他当成数组使用即可。

#include <iostream>
#include <vector>
 
int main()
{
    // 创建含有整数的 vector
    std::vector<int> v = {7, 5, 16, 8};
 
    // 将二个整数添加到 vector
    v.push_back(25);
    v.push_back(13);
 
    // 迭代并打印 vector 的值
    std::cout << "v = { ";
    for (int n : v)
        std::cout << n << ", ";
    std::cout << "};\n";
}

/*输出:
v = { 7, 5, 16, 8, 25, 13, };
*/
  1. vector容器的定义
#include <vector>   //头文件
vector<int> a;      //定义了一个int类型的vector容器a
vector<int> b[100]; //定义了一个int类型的vector容器b组

struct rec
{
    ···
};

vector<rec> c;            //定义了一个rec类型的vector容器c
vector<int>::iterator it; //vector的迭代器,与指针类似

  1. vector容器的操作
a.size()           //返回实际长度(元素个数),O(1)复杂度
a.empty()      //容器为空返回1,否则返回0,O(1)复杂度
a.clear()      //把vector清空
a.begin()      //返回指向第一个元素的迭代器,*a.begin()与a[0]作用相同
a.end()        //越界访问,指向vector尾部,指向第n个元素再往后的边界
a.front()      //返回第一个元素的值,等价于*a.begin和a[0]
a.back()       //返回最后一个元素的值,等价于*--a.end()和a[size()-1]
a.push_back(x) //把元素x插入vector尾部
a.pop_back()   //删除vector中最后一个元素
  1. 遍历容器的方法

(1)迭代器使用与指针类似,可如下遍历整个容器。

 for ( vector<int>::iterator it=a.begin() ; it!=a.end() ; it++ )
    cout<<*iterator<<endl;

(2) 当成数组使用。

for( int i=0;i<a.size();i++) cout<<a[i]<<endl;

代码示例:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    // 创建含有整数的 vector
    vector<int> v ;
    v.push_back(7);
    v.push_back(5);
    v.push_back(16);
    v.push_back(8);
 
    // 将二个整数添加到 vector
    v.push_back(25);
    v.push_back(13);
 
    // 迭代并打印 vector 的值
    cout << "v = { ";
    for ( vector<int>::iterator it=v.begin() ; it!=v.end() ; it++ )
        cout << *it << ", ";
    cout << "};\n";
    cout << "v = { ";
    for (int j = 0; j < v.size(); ++j) {
            cout << v[j] << ", ";
        }
    cout << "};\n";
}

队列的使用

队列的使用:
1.queue的定义方法

queue<string> myqueue;
queue<int> myqueue_int;
  1. queue的基本操作
front():返回 queue 中第一个元素的引用。
back():返回 queue 中最后一个元素的引用。
push(const T& obj):在 queue 的尾部添加一个元素的副本。
pop():删除 queue 中的第一个元素。
size():返回 queue 中元素的个数。
empty():如果 queue 中没有元素的话,返回 true

集合(set)的使用

在C++中,set是一个基于红黑树实现的关联容器,它可以自动将元素排序并保持唯一性。默认情况下,set使用元素类型的<运算符来比较和排序其元素。如果你想要一个自定义的排序准则,可以在声明set时指定一个比较函数或函数对象。

#include <bits/stdc++.h>
using namespace std;

// 1.set 的定义 set<数据类型> 变量名

set<int> intSet;
set<string> stringSet;

int main()
{
    string s1="测试1";
    string s2="测试2";
    string s3="测试3";

    //2. 插入操作
    stringSet.insert(s3);
    stringSet.insert(s1);

    //5. 返回集合元素数量
    printf("前2次插入操作完成后的元素数量为%d\n",stringSet.size());
    stringSet.insert(s2);
    printf("前3次插入操作完成后的元素数量为%d\n",stringSet.size());

    //6.遍历整个集合,借助迭代器实现
    //定义方式   容器类型< type> ::iterator name
    set<string> ::iterator  setStringIterator;
    for(setStringIterator=stringSet.begin();setStringIterator!=stringSet.end();setStringIterator++)
        cout<<*setStringIterator<<" ";
    puts("");

    //3. 删除操作
    stringSet.erase(s3);
    printf("删除操作完成后的元素数量为%d\n",stringSet.size());

    for(setStringIterator=stringSet.begin();setStringIterator!=stringSet.end();setStringIterator++)
        cout<<*setStringIterator<<" ";
    puts("");

    //4. 判断是否由此元素
    if(stringSet.count(s2)!=0) cout<<"存在元素"<<s2<<endl;
}

映射(map)的使用

map 是一个关联容器,它提供一对一的 hash。

第一个可以称为关键字(key),每个关键字只能在 map 中出现一次
第二个可能称为该关键字的值(value)

map 以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map 主要用于资料一对一映射(one-to-one)的情況,map 在 C++ 的內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。在 map 内部所有的数据都是有序的。
比如,像是管理班级内的学生,Key 值为学号,Value 放其他信息的结构体或者类。

  1. map 的定义:
//map的定义
map<char, int> mymap1;
map<string, int> mymap2;
  1. 容量:
int map.size();//查询map中有多少对元素
bool empty();// 查询map是否为空
  1. 插入
    map.insert(make_pair(key,value));
    //或者
    map.insert(pair<char, int>(key, value))
    //或者
    map[key]=value
  1. 遍历
map<string, string>::iterator it;
for (it = mapSet.begin(); it != mapSet.end(); ++it)
{
    cout << "key" << it->first << endl;

    cout << "value" << it->second << endl;
}
  1. 查找
m.count(key)//由于map不包含重复的key,因此m.count(key)取值为0,或者1,表示是否包含。
m.find(key)//返回迭代器,判断是否存在。

整体应用代码示例:

#include<bits/stdc++.h>
//#include<vector>
//#include<stack> 
//#include<string>
//#include<queue> 
//#include<deque>
//#include<map>
using namespace std;

//map是每个键对应一个值
//映射类似于函数的对应关系,每个x对应一个y.

//map特性:map会按照键的顺序从小到大自动排序,键的类型必须可以比较大小
void test01(){
	//初始化定义
	map<int, string> mp;

    // 插入元素
    mp.insert(make_pair(1, "One"));
    mp.insert(make_pair(2, "Two"));
    mp.insert(make_pair(3, "Three"));
    mp.insert(make_pair(4, "Four"));

    // 查看元素是否存在
    if (mp.count(2) > 0) {
        cout << "Key 2 exists!" << endl;
    }

    // 查找元素
    map<int,string>::iterator it = mp.find(3);
    if (it != mp.end()) {
        cout << "Value of key 3: " << it->second << std::endl;
    }

    // 删除元素
    mp.erase(2); // 通过键删除元素
    mp.erase(mp.find(4)); // 通过迭代器删除元素

    // 清空map
    mp.clear();

    // 判断map是否为空
    if (mp.empty()) {
        cout << "Map is empty!" << std::endl;
    }
}

void test02(){
	
	/*mp.find(key) 返回键为key的映射的迭代器 $O(logN) 
	注意:用find函数来定位数据出现位置,它返回一个迭代器。当数据存在时,返回数据所在位置的迭代器,数据不存在时,返回mp.end() 
	mp.erase(it) 删除迭代器对应的键和值O(1)
	mp.erase(key) 根据映射的键删除键和值 O(logN) 
	mp.erase(first,last) 删除左闭右开区间迭代器对应的键和值 O(last-first) 
	mp.size() 返回映射的对数$ O(1)$ mp.clear() 清空map中的所有元素O(N) 
	mp.insert() 插入元素,插入时要构造键值对 
	mp.empty() 如果map为空,返回true,否则返回false 
	mp.begin() 返回指向map第一个元素的迭代器(地址) 
	mp.end() 返回指向map尾部的迭代器(最后一个元素的下一个地址) 
	mp.rbegin() 返回指向map最后一个元素的迭代器(地址) 
	mp.rend() 返回指向map第一个元素前面(上一个)的逆向迭代器(地址) 
	mp.count(key) 查看元素是否存在,因为map中键是唯一的,所以存在返回1,不存在返回0 
	mp.lower_bound() 返回一个迭代器,指向键值>= key的第一个元素 
	mp.upper_bound() 返回一个迭代器,指向键值> key的第一个元素
	*/
}


void test03(){
	map<int,int> mp;
	mp[1] = 2;
	mp[2] = 3;
	mp[3] = 4;
	map<int,int>::iterator it = mp.begin();
	while(it != mp.end()) {
		cout << it->first << " " << it->second << "\n";
		it ++;
	}
	cout<<"******"<<endl;
	map<int,int> mp1;
	mp1[1] = 2;
	mp1[2] = 3;
	mp1[3] = 4;
	map<int,int>::reverse_iterator it1 = mp1.rbegin();
	while(it1 != mp1.rend()) {
		cout << it1->first << " " << it1->second << "\n";
		it1 ++;
	}

}

void test04(){
	map<int, int> m;
    m.insert(make_pair(1, 2));
    m.insert(make_pair(2, 2));
    m.insert(make_pair(1, 2));
    m.insert(make_pair(8, 2));
    m.insert(make_pair(6, 2));
	map<int, int>::iterator it1 = m.lower_bound(2); 
	cout << it1->first << "\n";//it1->first=2 
	map<int, int>::iterator it2 = m.upper_bound(2); 
	cout << it2->first << "\n";//it2->first=6
	//?? 为什么不是8 
	cout<<"***"<<endl;
	
	map<int,int>::iterator it = m.begin();
	while(it != m.end()) {
		cout << it->first << " " << it->second << "\n";
		it ++;
	}

}

int main()
{
	cout<<"test01():"<<endl;
	test01();
	cout<<"************"<<endl;
	cout<<"test02():"<<endl;
	test02();
	cout<<"************"<<endl;
	cout<<"test03():"<<endl;
	test03();
	cout<<"************"<<endl;
	cout<<"test04():"<<endl;
	test04();
	
	return 0;
}

算法设计例题

例题一:(容器vector)快递的分拣

【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题,算法,c++,开发语言,数据结构

样例:
输入:

10 
10124214 北京
12421565  上海
sdafasdg213 天津
fasdfga124 北京
145252  上海
235wtdfsg 济南
3242356fgdfsg 成都
23423 武汉  
23423565f 沈阳
1245dfwfs 成都

输出:

北京 2
10124214
fasdfga124
上海 2
12421565
145252
天津 1
sdafasdg213
济南 1
235wtdfsg
成都 2
3242356fgdfsg 
1245dfwfs 
武汉 1
23423
沈阳 1
23423565f 

题解:

//1. 创建有个vector容器 用来保存地址
vector<string> city;
//2. 再创建一个 用来保存快递单号
vector<string> dig[1000];
//3. 定义一个映射函数,因为城市可能会再次出现,我们需要知道之前有没有。
//4. 读入操作并按照顺序进行存放

题解示例:

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

//创建有个vector容器 用来保存地址
vector<string> city;
//再创建一个 用来保存快递单号
vector<string> dig[1000];

int Myfind(string s){
    //寻找到该城市的位置 下标
    for(int i=0;i<city.size();i++)
    {
        if(city[i]==s) return i;
    }
    return -1;
}

int main()
{

    int n;
    cin>>n;//输入有几个快递

    for(int i=0;i<n;i++)
    {
        string d,c;
        
        cin>>d>>c;///输入快递单号 和 快递地址
        int flag=Myfind(c);//输出该地址的位置
        if(flag==-1){//如果没找到这个地址
            city.push_back(c);//把这个城市添加到city这个容器中 
            dig[city.size()-1].push_back(d);//在对应位置的数值后添加 快递单号
        }
        else  dig[flag].push_back(d);//在对应位置的数值后添加 快递单号
    }
    for(int i=0;i<city.size();i++)
    {
        cout<<city[i]<<" "<<dig[i].size()<<endl;
        for(int j=0;j<dig[i].size();j++)
            cout<<dig[i][j]<<endl;
    }
}

例题二:(queue)银行排队问题

【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题,算法,c++,开发语言,数据结构

输入样例:

5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V

输出样例:

Adel
CLZ
laozhao

题解:

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

queue<string> V; // VIP队列
queue<string> N; // 普通队列

int main()
{
    int M;
    cin >> M; // 输入操作的次数

    while (M--) // 每次进行一个操作
    {
        string op, name, type;
        cin >> op; // 读入 进入还是出去
        if (op == "IN")
        {
            cin >> name >> type; // 读取名字 和 类型

            if (type == "V")
                V.push(name); // 如果是VIP类型,加入VIP队列
            else
                N.push(name); // 否则加入普通队列
        }
        else
        {
            cin >> type; // 读取类型

            if (type == "V")
                V.pop(); // 如果是VIP类型,从VIP队列出队
            else
                N.pop(); // 否则从普通队列出队
        }
    }

    // 打印结果
    while (V.size())
    {
        cout << V.front() << endl; // 输出VIP队列中的元素
        V.pop(); // 出队
    }
    while (N.size())
    {
        cout << N.front() << endl; // 输出普通队列中的元素
        N.pop(); // 出队
    }

    return 0;
}

例题三:(map)重复的单词

【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题,算法,c++,开发语言,数据结构

输入样例:

5
sdfggfds
fgsdhsdf
dsfhsdhr
sdfhdfh
sdfggfds

输出

sdfggfds

题解:

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

map<string,bool> mp;
int main ()
{

    int n;
    string ans="NO";
    cin>>n;
    for(int i=0;i<n;i++)
    {
        string word;
        cin>>word;
        if(mp.count(word)){
            ans=word;
            break;
        }

        else mp[word]=1;
    }
    cout<<ans<<endl;

}

感谢阅读!!!
更多算法例题链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题)文章来源地址https://www.toymoban.com/news/detail-850956.html

到了这里,关于【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 10.1 C++ STL 模板适配与迭代器

    STL(Standard Template Library)标准模板库提供了模板适配器和迭代器等重要概念,为开发者提供了高效、灵活和方便的编程工具。模板适配器是指一组模板类或函数,它们提供一种适配机制,使得现有的模板能够适应新的需求。而迭代器则是STL中的令一种重要的概念,它是一个抽

    2024年02月12日
    浏览(44)
  • 数据结构与算法—二叉树数组表示(ArrayBinTree)、二叉树的链式表示(LinkedBinTree)的基于C++模板代码实现

    1、二叉树的顺序表示:ArrayBinTree.h 二叉树的顺序表示法操作方便,但缺点是容易造成存储空间浪费。 这是一个用数组实现的二叉树类模板。它可以创建一个空树,也可以在指定的位置插入结点并设置结点的值,可以删除子树,并支持逐层遍历。使用该类时,需要提供一个元

    2024年02月06日
    浏览(43)
  • 数据结构与算法----详解二叉树的遍历(迭代、递归)

    ❤️ 作者简介 :大家好我是小鱼干儿♛是一个热爱编程、热爱算法的大三学生,蓝桥杯国赛二等奖获得者 🐟 个人主页 :https://blog.csdn.net/qq_52007481 ⭐ 个人社区 :【小鱼干爱编程】 🔥 算法专栏 :算法竞赛进阶指南 💯 刷题网站 :虽然市面上有很多的刷题网站,但是里面

    2024年01月24日
    浏览(53)
  • 【C++入门】STL容器--vector底层数据结构剖析

    目录  前言  1. vector的使用       vector的构造  vector迭代器  vector空间相关的接口  vector 功能型接口  find  swap  insert  erase 2. vector内部数据结构剖析 reserve  push_back和pop_back size、capacity、empty、operator[ ];  insert和erase resize swap  拷贝构造和赋值重载 构造函数补充  迭代器

    2024年01月25日
    浏览(56)
  • 算法分析与设计考前冲刺 (算法基础、数据结构与STL、递归和分治、 动态规划、贪心算法、 回溯算法)

    算法分析与设计考前冲刺 算法基础 算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。 程序是算法用某种程序设计语言的具体的 具体实现 算法特征: 有穷性(有限步) 确定性 输入 输出 可行性(有限时间) 算法的复杂性: 时间复杂性 和空间复

    2024年02月02日
    浏览(44)
  • 【C++ | 数据结构】从哈希的概念 到封装C++STL中的unordered系列容器

    引入: 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O( l o g 2 N log_2 N l o g 2 ​ N ),搜索的效率取决于搜索过程中元素的比较次数。 尽管平

    2024年01月22日
    浏览(43)
  • 深入探究C++中的STL:容器、迭代器与算法全解析

    Standard Template Library:标准模板库 是一个基于泛型的C++类模板库由Alexander Stepanov于1994年开发 其目的是为了提供一致通用和高效的数据结构和算法,同时不限制用户所处理的数据类型和编程范式。STL的原型最初由Andrew Koenig和其它C++专家小组进行设计并在1995年C++标准委员会的推

    2024年02月05日
    浏览(72)
  • 【C++】数据结构与算法:常用排序算法

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍常用排序算法。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 排序算法是计算机科学中常见的一类算法,用于将一组数据按照特定的顺序进行排

    2024年02月14日
    浏览(48)
  • 标准模板库STL——迭代器

    目录 四类迭代器概述 代码段 普通正向迭代器 普通反向迭代器 常量正向迭代器 常量反向迭代器 四类迭代器 普通正向迭代器 iterator 常量正向迭代器 const_iterator 普通反向迭代器 reverse_iterator 常量反向迭代器 const_reverse_iterator 解释说明 普通表示可以读元素,也可以写元素; 常量

    2024年02月12日
    浏览(35)
  • 【数据结构与算法C++实现】3、排序算法

    原视频为左程云的B站教学 外层循环 :n个数需要冒n-1个泡上去,剩下的一个必然是最小的。所以外层循环执行n-1轮 内层循环 :比大小,第1个泡需要比n-1次,第2个泡,比较n-2次… 选择: 每次从待排序序列中选择 最小的一个 放在已排序序列的后一个位置 原理类似于对扑克牌

    2024年02月11日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包