卡码网_C++基础使用

C++基础使用

Vector

初始化

	vector<int> arr;
	vector<int> arr = vector<int>(n,0);
	vector<int> arr(n,0);

加入元素

	arr.push_back(num);

获取长度

	int i = arr.size()

其余arr用法和数组相同

String

初始化

string s1; // 默认初始化,s1是一个空的字符串
string s2 = "hello"; // 初始化一个值为hello的字符串
string s3(5, 'a') // 连续5个字符a组成的串,即'aaaaa'

字符串拼接

string s1 = "hello";
string s2 = "world";
string s3 = s1 + " " + s2; 

获取长度

int length = s1.size();

下标访问

char c1 = s1[1]; 

判空

if (s1.empty()) {
  // 如果字符串为空则返回true, 否则返回false
}

输入输出

int main() {
  string s; // 定义空字符串
  // 将标准输入的内容读入到字符串s中,从第一个真正的字符(去掉空格、换行等)开始读取,直到遇到空白停止
  cin >> s; 
  cout << s << endl; // 输出s
  return 0;
}

读取行

#include <iostream>
#include <string>
using namespace std;
int main() {
  string line;
  // 获取用户输入的一行文本,并将其存储到line变量中
  getline(cin, line);
  // 输出读取的一行文本
  cout << line << endl;
}

Set

类型

和数学中的集合一样,C++中的集合set用于允许存储一组不重复的元素, 并且元素的值按照有序排列, set基于红黑树实现,支持高效的关键字查询操作, 可以用来检查一个给定关键字是否在set中。

无序集合unordered-set类似于集合(Set),但不会按照元素的值进行排序,而是由哈希函数的结果决定的。

multiset 则是一个用于存储一组元素,允许元素重复,并按照元素的值进行有序排列的集合。

集合底层实现是否有序数值是否可以重复
std::set红黑树有序
std::multiset红黑树有序
std::unordered_set哈希表无序

Set的使用

使用集合set需要先引入头文件

// 引入<unordered_set>头文件
#include <unordered_set>
// 引入set头文件
#include <set>

创建一个集合的写法如下

// 创建一个存储整数的无序集合
unordered_set<int> mySet;
// 创建一个存储整数的set
set<int> mySet;
// 创建一个存储整数的 multiset
multiset<int> myMultiSet; 

想要向集合中插入元素需要使用insert()方法

 // 向集合中插入元素
mySet.insert(1);
mySet.insert(2);
mySet.insert(3);

想要往集合中删除元素需要使用erase方法

mySet.erase(1);

find() 方法用于查找特定元素是否存在于集合中,如果 find() 方法找到了要查找的元素,它会返回指向该元素的迭代器,如果未找到要查找的元素,它会返回一个指向集合的 end() 的迭代器,表示未找到。通过比较find()方法返回的迭代器是否等于 end(),可以确定集合中是否有查找的元素。

// 判断元素是否在集合中, 只要不等于end(), 说明元素在集合中
if (mySet.find(i) != mySet.end()) {
}

迭代器

迭代器iterator提供了一种类似指针的接口,可以用来遍历访问容器(比如数组、集合)中的元素,并执行各种操作。

可以理解为,迭代器和下标运算符的作用一样,用来访问容器中的元素,并且迭代器可以从一个元素移动到另外一个元素。

迭代器都拥有名为begin()end()的成员,表示指向第一个元素和最后一个元素的下一个元素的迭代器(尾后迭代器),如果容器为空,则beginend返回的是同一个迭代器。

可以使用比较运算符来判断两个迭代器是否相等,如果迭代器想要从一个元素移动到另外一个元素,可以使用递增++运算符和递减--运算符,表示向前(后)移动一个位置。

通过解引用*可以获取迭代器所指的对象,下面的示例表示了vector的遍历。

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

int main() {
    vector<int> myVector = {1, 2, 3, 4, 5};

    // 使用迭代器遍历容器
      // vector<int>::iterator it  用于创建一个能读取<vector>int 元素的迭代器it,最初指向begin()
      // ++it表示迭代器的移动
    for (vector<int>::iterator it = myVector.begin(); it != myVector.end(); ++it) {
        cout << *it << " "; // 通过解引用获取迭代器所指的对象
    }

    cout << endl; 

    return 0;
}

Map

类型

我们常常把map称之为映射,就是将一个元素(通常称之为key键)与一个相对应的值(通常称之为value)关联起来,比如说一个学生的姓名(key)有与之对应的成绩(value),它们是一一对应的,就好像一把钥匙开一扇门,在map中键是唯一的,也只有一个唯一的确定的值。

在C++中, map 提供了以下三种数据结构,其底层实现以及优劣如下表所示:

map中的键是唯一的,但是multimap则没有此限制

映射底层实现是否有序数值是否可以重复
std::map红黑树key有序key不可重复
std::multimap红黑树key有序key可重复
std::unordered_map哈希表key无序key不可重复

std::unordered_map 的key值存储是无序的,底层实现为哈希表,查找速度更快,如果不需要排序而只是快速查找键对应的值,可以考虑使用。

std::map 和std::multimap 的底层实现是红黑树,它的key值存储是有序的,如果需要对键值对进行自定义排序,可以考虑使用std::map

map的使用

使用映射容器需要引入头文件<unordered_map>或者<map>

// 引入unordered_map头文件,包含unordered_map类型
#include <unordered_map>
// 引入map头文件,包含map类型和multimap类型
#include <map>

想要声明map映射关系,需要指定键的类型和值的类型。

// 声明一个整数类型映射到整数类型的 无序映射
unordered_map<int, int> uMap;
// 声明一个将字符串映射到整数的`map`,可以这样声明:
map<string, int> myMap;

想要插入键值对key-value, 需要使用insert()函数或者使用[]操作符来插入。如果键不存在,[]操作符将会创建一个新的键值对,将其插入到map中,并将值初始化为默认值(对于整数来说,默认值是0)。

uMap[0] = 10;
uMap[10] = 0;

myMap["math"] = 100;
myMap["english"] = 80;

set类似,可以使用find函数来检查某个键是否存在于map中,它会返回一个迭代器。如果键存在,迭代器指向该键值对,否则指向map的末尾。

if (myMap.find("math") != myMap.end()) {
    // 键存在
} else {
    // 键不存在
}

你可以使用范围for循环来遍历map中的所有键值对,进行各种操作。

for(const pair<int,int>& kv:umap) {
  
}

当使用范围for循环遍历map时,我们需要声明一个变量kv来存储每个键值对。这个变量的类型通常是pair类型,下面就让我们详细解释一下const pair<int,int>& kv:umap

const用于声明一个不可修改的变量,这意味着一旦变量被初始化,就不能再修改其值。常量通常用大写字母表示

因为const声明的变量一旦创建后就无法修改值,所以必须初始化。

const double PI = 3.1415926

在这里,const关键字表示你只能读取容器中的元素,而不能修改它们。

pair<int, int>定义了kv也就是键值对的数据类型是pair, C++中的pair类型会将两个不同的值组合成一个单元, 常用于存储键值对,创建pair的时候,也必须提供两个类型名,比如上面的pair对象,两个值的类型都是int, 在使用时通过firstsecond 成员来访问 pair 中的第一个和第二个元素, 它的 first 成员存储键,而 second 成员存储值。

&:这个符号表示kv是一个引用(reference),而不是值的拷贝, 如果不使用引用的话,那在每次循环迭代中都会重新创建一个新的pair对象来复制键值对,而这会导致不必要的内存分配和拷贝操作。

范围for循环

C++11引入了范围for循环,用于更方便地遍历容器中的元素。这种循环提供了一种简单的方式来迭代容器中的每个元素,而不需要显式地使用迭代器或索引。

for (类型 变量名 : 容器) {
    // 在这里使用一个变量名,表示容器中的每个元素
}

比如下面的代码就表示使用范围for循环遍历一个容器

std::vector<int> numbers = {1, 2, 3, 4, 5};

// 使用范围for循环遍历向量中的元素
for (int num : numbers) {
    std::cout << num << " ";
}

范围for循环不会修改容器中的元素,它只用于读取元素。如果需要修改容器中的元素,需要使用传统的for循环或其他迭代方式。

此外,还可以使用auto关键字来让编译器自动推断元素的类型,这样代码会更通用

// 使用auto关键字自动推断元素的类型
for (auto num : numbers) {
    std::cout << num << " ";
}

#include <stack> // 引入stack头文件

然后就可以通过stack数据类型 栈名称这样的形式来创建一个栈并进行操作了

 stack<int> st; // 创建一个int类型的栈

栈的常用操作主要有以下几种:

  • empty(): 判断栈是否为空栈,如果为空栈返回true, 否则或者false
  • push(): 进栈操作,将新的元素放入到栈中,新的元素成为栈顶元素。
  • pop(): 出栈操作,栈顶元素从栈中离开
  • top(): 获取栈顶元素,但是不会移除它
  • size(): 获取栈的长度,即栈中元素的数量
st.push(1);
st.push(10);
st.push(100); // 往栈中添加元素,现在栈底元素是1,栈顶元素是100

st.pop(); // 移除栈顶元素100,新的栈顶元素是10

int topNumber = st.top(); // 获取栈顶元素10

bool isEmpty = st.empty(); // 如果栈为空,返回true;否则返回false

int stackSize = st.size(); // 获取栈的长度(元素数量)

队列

在C++中,你可以使用标准库提供的 std::queue 来创建和操作队列,不过这需要引入头文件queue

// 引入queue头文件
#include <queue>

创建一个队列和创建一个栈的写法是相似的,需要指定队列中元素的类型,不过这也意味着队列中的元素必须是相同的数据类型,下面的代码表示创建一个字符串类型的队列。

queue<string> q; // 创建一个字符串类型的队列

队列的常用操作主要有以下几种:

  • empty(): 判断队列是否为空,如果队列为空返回true, 否则返回false
  • push(): 入队操作,将新的元素添加到队列的尾部。
  • pop(): 出队操作,移除队列的头部元素。
  • front(): 访问队列的头部元素,但不会将其移除。
  • size(): 获取队列的长度,即队列中元素的数量。
q.push("Jack");
q.push("Mike");  // 入队了两个名称字符串

q.pop(); // 移除队列头部的元素

string name = q.front(); // 获取队列头部的元素但是不会将其移除

bool isEmpty = q.empty(); //  如果队列为空,返回true;否则返回false

int queueSize = q.size(); // 获取队列中元素的数量
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值