从C语言的使用转换到C++(下篇)——刷题、竞赛篇

简介: 我们上篇文章讲述了C++中的一些基础语法和常用函数(从C语言的使用转换到C++(上篇)——刷题、竞赛篇),我们本篇文章讲述C++STL的使用。

 我们上篇文章讲述了C++中的一些基础语法和常用函数(从C语言的使用转换到C++(上篇)——刷题、竞赛篇),我们本篇文章讲述C++STL的使用。


一、C++STL的简介


STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。

 STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组;

 STL另一个重要特性是它不是面向对象的。为了具有足够通用性,STL主要依赖于模板而不是封装,继承和虚函数(多态性)——OOP的三个要素。你在STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得STL的组件具有广泛通用性的底层特征。另外,由于STL是基于模板,内联函数的使用使得生成的代码短小高效。


二、STL的使用详解

2、1 STL之动态数组vector的使用


 在c语言中我们学习了数组的使用,如:int arr[10]。我们在使用的过程中也发现其缺点,我们不能随意的改变数组的长度。在C++中我们可以使用动态数组vector来完全代替c语言中的数组。动态数组vector能够在运行阶段设置数组的长度、在末尾和中间插入数据、长度可以任意改变。相对c语言中的数组来说,动态数组vector很方便、很实用。


 动态数组vector在头文件vector中,也在命名空间std里面。所以使用动态数组vector时,我们要引入#include<vector>和using namespace std;


 vector、stack、queue、map、set 这些在C++中都叫做容器,这些容器的大小都可以用.size()获取到。我们快来看一下具体的使用方法:


#include<iostream>
#include<vector>
using namespace std;
int main()
{
  vector<int> v1;  //定义一个的整形动态数组vector v1,定义的时候并没有分配大小
  cout << v1.size() << endl;  //输出动态数组vector v1的大小
  return 0;
}


 在上面的代码中,我们简单的定义了动态数组vector,并且计算了其大小。注意:动态数组vector在C++中叫做容器,我们可以用.size()来计算出其大小。

 上述我们在定义的时候并没有分配大小,所以用.size()来计算出其大小时,结果为0



c512be4577714cbea651ea2ef084c012.png


我们接着看动态数组vector的其他用法:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
  //vector<int> v1;  //定义一个的整形动态数组vector v1,定义的时候并没有分配大小
  //cout << v1.size() << endl;  //输出动态数组vector v1的大小
  vector<int> v(10);  //直接定义长度为10的int数组,默认每个元素的值为0
  vector<int> v1;
  v1.resize(8);  //先定义了一个vector v1的动态数组,然后再用resize设置长度为8
  vector<int> v2(100, 9);  //把长度为100的数组的所有值都初始化为9
  v[1] = 2;  //可以直接用下标来访问,也可用迭代器访问
  return 0;
}



 不管是vector 、 stack 、 queue 、 map还是set 都有很多好用的方法,这些方法都可以在www.cplusplus.com官方网站中直接查询官方文档,上面有方法的讲解和代码示例。比如进入官网搜索 vector ,就会出现 vector拥有的所有方法,点进去一个方法就能看到这个方法的详细解释和代码示例~当然我们平时写算法用不到那么多方法啦,只有几个是常用的。以下是一些常用的 vector方法:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
  vector<int> a; //定义时不指定vector的大小
  cout << a.size() << endl; // a的大小为0
  for (int i = 0; i < 10; i++) 
  {
    a.push_back(i); // 向a中末尾插入0到9
  }
  cout << a.size() << endl; // a的大小为10;
  vector<int> b(15);  //定义时指定b的大小为15,各个元素默认值为0
  cout << b.size() << endl;  //b的大小为15
  for (int i = 0; i < b.size(); i++) 
  {
    b[i] = 15;  //给b中的每个元素赋值
  }
  for (int i = 0; i < b.size(); i++) 
  {
    cout << b[i] << " ";  //输出b中的元素
  }
  cout << endl;
  vector<int> c(20, 2);  //定义时指定c的大小为20,各个元素默认值为2
  for (int i = 0; i < c.size(); i++) 
  {
    cout << c[i] << " ";  //输出c中的元素
  }
  cout << endl;
  for (auto it = c.begin(); it != c.end(); it++)   //迭代器访问
  {
    cout << *it << " ";
  }
  return 0;
}


容器vector , set , map这些遍历的时候都是使用迭代器访问的,(c.begin()是一个指针,指向容器的第一个元素,c.end()指向容器的最后一个元素的后一个位置)。


 上述代码的运行结果如下图:

2、2 STL之集合set的使用


 set是集合,一个 set里面的各元素是各不相同的,而且 set 会按照元素进行从小到大排序。以下是set的常用用法:

#include <iostream>
#include <set>
using namespace std;
int main()
{
  set<int> s;  //定义一个集合
  s.insert(1);  //向集合里面插入一个1
  cout << *(s.begin()) << endl; // ᬌ输出集合中的第一个元素
  for (int i = 0; i < 10; i++) 
  {
    s.insert(i); // 向集合中插入十个元素
  }
  for (auto it = s.begin(); it != s.end(); it++) 
  {
      cout << *it << " ";
  }
  cout << endl << (s.find(2) != s.end()) << endl; //查找集合s中的值,如果结果等于s.end()表示未找到(因为s.end()表示s的最后一个元素的下一个元素所在的位置)
    cout << (s.find(10) != s.end()) << endl; // s.find(10) != s.end()
  s.erase(1); // s.erase( 1);//删除集合s中的1这个元素
  cout << (s.find(1) != s.end()) << endl; //这时候元素1就应该找不到了
  return 0;
}


上述代码的运行结果如下图:

2、3 STL之映射map的使用


 map是键值对,比如一个人名对应一个学号,就可以定义一个字符串string类型的人名为“键”,学号int类型为“值”,如map<string, int>m;当然键、值也可以是其它变量类型。map 会自动将所有的键值对按照键从小到大排序,map使用时的头文件 #include <map>以下是 map中常用的方法:

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
  map<string, int> m;  //定义一个空的map m,键是string类型的,值是int类型的
  m["hello"] = 2;   //将key为"hello", value为2的键值对(key-value)存入map中
  cout << m["hello"] << endl;  //访问map中key为"hello"的value,如果key不存在,则返回0
  cout << m["world"] << endl;  //返回0
  m["world"] = 3;  //将"world"键对应的值修改为3
  m[","] = 1;  //设立一组键值对,键为",”值为1
  for (auto it = m.begin(); it != m.end(); it++) 
  {
    //用迭代器遍历,输出map中所有的元素,键用it->first获取,值用it->second获取
    cout << it->first << " " << it->second << endl;  
  }
  //访问map的第一个元素,输出它的键和值
  cout << m.begin()->first << " " << m.begin()->second << endl;
  //访问map的最后一个元素,输出它的键和值
  cout << m.rbegin()->first << " " << m.rbegin()->second << endl;
  //输出map的元素个数
  cout << m.size() << endl;
  return 0;
}

 上述代码的运行结果如下图:

2、4 STL之栈stack的使用


 栈stack在头文件 #include <stack>中,是数据结构里面的栈。我们知道栈是先进后出的一个原则。以下是常用用法:  

#include <iostream>
#include <stack>
using namespace std;
int main() 
{
  stack<int> s;  //定义一个空栈s
  for (int i = 0; i < 6; i++) 
  {
    s.push(i);  //将元素i压入栈s中
  }
  cout << s.top() << endl;  //访问s的栈顶元素
  cout << s.size() << endl;  //输出s的元素个数
  s.pop(); //移除栈顶元素
  cout << s.size() << endl;  //输出s的元素个数
  cout << s.top() << endl;  //访问s的栈顶元素
  return 0;
}



 上面代码的运行结果如下图:

2、5 STL之队列queue的使用



队列queue 在头文件 #include<queue>中,是数据结构里面的队列。队列遵循先进先出的原则。以下是常用用法:

#include <iostream>
#include <queue>
using namespace std;
int main() 
{
  queue<int> q;  //定义一个空队列q
  for (int i = 0; i < 10; i++) 
  {
    q.push(i);  //将i的值依次压入队列q中
  }
  cout << q.front() << " " << q.back() << endl;  //访问队列的队首元素和队尾元素
  cout << q.size() << endl;  //输出队列的元素个数
  q.pop();  //移除队列的队首元素
  cout << q.front() << endl;
  cout << q.size() << endl;  //输出队列的元素个数
  return 0;
}



上述代码的运行结果如下图:

2、6 STL之unordered_map和unordered_set的使用


 unordered_map在头文件#include<unordered_map>中,unordered_set 在头文件#include<unordered_set>中。unordered_map和 map(或者unordered_set和 set )的区别是,map 会按照键值对的键 key进行排序(set里面会按照集合中的元素大小进行排序,从小到大顺序),而unordered_map(或者unordered_set)省去了这个排序的过程,如果偶尔刷题时候用map或者set 超时了,可以考虑用unordered_map(或者_unordered_set)缩短代码运行时间、提高代码效率。至于用法和map .set是一样的。


三、总结


 学到这里我们发现,用C++来刷题确实会方便很多。例如,STL中已有栈、队列等容器。而c语言却没有,有些题目做起来就麻烦了很多。


 STL的使用给我们带来了很大的便利,也是哦我们重点掌握的内容。学到这里基本上用C++写算法题没有问题。我们需要做的就是通过刷题,进而更加熟练的掌握。


 希望以上内容对你有所帮助,感谢阅读ovo~

相关文章
|
3月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
143 26
|
安全 编译器 C语言
C++入门1——从C语言到C++的过渡
C++入门1——从C语言到C++的过渡
195 2
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
274 10
|
10月前
|
算法 编译器 C语言
【C语言】C++ 和 C 的优缺点是什么?
C 和 C++ 是两种强大的编程语言,各有其优缺点。C 语言以其高效性、底层控制和简洁性广泛应用于系统编程和嵌入式系统。C++ 在 C 语言的基础上引入了面向对象编程、模板编程和丰富的标准库,使其适合开发大型、复杂的软件系统。 在选择使用 C 还是 C++ 时,开发者需要根据项目的需求、语言的特性以及团队的技术栈来做出决策。无论是 C 语言还是 C++,了解其优缺点和适用场景能够帮助开发者在实际开发中做出更明智的选择,从而更好地应对挑战,实现项目目标。
379 0
|
算法 机器人 C语言
ROS仿真支持C++和C语言
ROS仿真支持C++和C语言
415 1
|
机器学习/深度学习 编译器 C语言
C语言刷题(中)(保姆式详解)
C语言刷题(中)(保姆式详解)
82 0
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
150 0
|
29天前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
673 0
|
3月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
253 15
|
9月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
400 23

热门文章

最新文章