C++ 基础知识总结

前言

打算刷leetcode,有些放不下Python和C++这两种语言,常有些人说用Python刷算法是作弊。感觉有些道理吧,这不认真复习一下C++的基础。

string(字符串)

  • 头文件及定义
#include <string>		//头文件
string str = "abcd";	//使用

访问方式:下标或迭代器访问
特殊运算:+=(拼凑)、==、!=、<、<=、>、>=(这个不错)
常用方法:insert(pos,string)substr(value)size()/length()erase(地址)
好用方法:push_back()、pop_back()

分割

方法一:C语言的strtok函数

注:当非第一次调用strtok函数时,第一个参数可以设置为NULL,表示函数继续从上一次调用隐式保存的位置,继续分割字符串。

char s[] = "my name is lmm";
char *p;
const char *delim = " ";
p = strtok(s, delim);
while(p) {
    cout << p << endl;
    p = strtok(NULL, delim);
}

方法二:string的find+substr函数

vector<string> split(const string &str,const string &pattern)
{
    vector<string> res;
    if(str == "")   //考虑字符串为空的情况
        return res;
    //为字符串末尾添加分隔符,方便截取最后一段
    string strs = str + pattern;
    //查找子字符串第一次出现的位置,未找到返回string::npos
    size_t pos = strs.find(pattern);    
    while(pos != strs.npos) 
    {
        string curr = strs.substr(0,pos);   //从第0个下标开始截取pos长度的字符串,curr为分割字符串
        res.push_back(curr);    //emplace_back
        //去掉已分割的字符串,在剩下的字符串中进行分割
        strs = strs.substr(pos+pattern.size(),strs.size());  //截取长度超过总长度也可
        pos = strs.find(pattern);
    }
    return res;
}

方法三:stringstream函数(推荐)

需要使用istringstream(字符串输入流)构建字符串流。

string str = "this is a test";
istringstream iss(str);	//输入流
string token;			//接收缓冲区
char split = ' ';
while(getline(iss,token,split))
{
    cout<<token<<endl;	//输出
}

遍历

string S = "1  2 3  41";
//区间for
for(char const &s:S)
{
    if(s==' ') continue;
    newS += s;
}

//for_each
std::for_each(s.begin(), s.end(), [] (char const &c) {
        std::cout << c << ' ';
    });

判空

string str;
if(str.empty())	{}		//方法一:效率最高且最常用
if(str.size() == 0)	{}	//方法二
if(str == "")			//方法三:与空串比较

查找find

string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数)

string s = "sdvsvber";
cout<<s.find('s')<<endl;    //0
cout<<s.find("d")<<endl;    //1
cout<<s.find("vsv")<<endl;  //2
if (s.find("vsv") == s.npos) {
	cout<<"not find"<<endl;		// not find
	cout<<s.find('a')<<endl;    //18446744073709551615,数值会有所不同
}

容器

序列式容器

通用方法

  • begin()、end()、cbegin()、cend() (array具有,vector具有,deque具有)
  • rbegin()、rend()、crbegin()、crend() (array具有,vector具有,deque具有)
  • max_size() (array具有,vector具有)
  • empty() (array具有,vector具有,stack具有,queue、priority_queue、deque具有)
  • at(n) 可用于判断是否越界 (list不可用) (array具有,vector具有)
  • front()、back() (array具有)
  • swap (array具有,vector具有,stack具有、queue、priority_queue、deque具有)

注:带c开头指const遍历。

array(C11新增)

  • 头文件及定义
#include <array>				//头文件
array<typename, number> name;	//使用

访问方式:通过迭代器和下标访问访问方式

  • 常用方法
    • empty() 判断size()==0
    • front()、back()
    • data()
    • fill(val) 将 val 这个值赋值给容器中的每个元素

vector(变长数组)

  • 头文件及定义
#include <vector>		//头文件
vector <typename> name;	//使用

访问方式:通过迭代器和下标访问

  • 常见迭代方式
vector <int> vec = {1,2,3,4,5};
// C风格方式
for (size_t i = 0; i < vec.size(); i++)
{
	cout<<vec[i]<<endl;
}

//for区间遍历
for (auto it : vec)
{
	cout<<vec[i]<<endl;
}

//迭代器
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
{
	cout<<*it<<endl;
}

//for_each
for_each(vec.begin(), vec.end(), [](const int& val)->void{cout << val << endl; });
  • 常用方法

    • push_back()、emplace_back()、insert()、emplace()
    • erase(地址)、clear()
    • pop_back()
    • resize()、reverse()
  • 多维数组申请

//方式一 m * n
vector<vector<int>> vec(m,vector<int>(n));
//方式二m * n
vector<vector<int>> vec;
vec.resize(m,vector<int>(n));

stack(栈)

  • 头文件及定义
#include <stack>		//头文件
stack <typename> name;	//使用

只能通过top()访问队首元素

  • 常用方法
    • top()
    • push()
    • pop()
    • emplace(),效率比push低

queue(队列)

  • 头文件及定义
#include <queue>		//头文件
queue <typename> name;	//使用

只能通过front()访问队首元素,back()访问队尾(先empty()判断是否为空)

  • 常用方法
    • front()、back()
    • push(x)
    • pop()
清空队列
// 方法一:直接赋空值
queue<int> d;
// ......
q1 = queue<int>();

// 方法二:遍历出队列
while (!Q.empty()) Q.pop();

// 方法三:使用swap,最高效
queue<int> empty;
swap(empty, q);

deque(双端队列)

  • 头文件及定义
#include <deque>		//头文件
deque <typename> name;	//使用

访问方式:通过迭代器访问

  • 常用方法
    • push_front()、emplace_front()、push_back()、emplace_back()、emplace()
    • pop_front()、pop_back()
    • front()、back()
    • resize()、size()

priority_queue(优先队列)

注:默认优先级最大的先出

  • 头文件及定义
#include <queue>				//头文件
priority_queue<typename> name;	//使用(默认大根堆)

使用场景:可用于贪心问题(不用排列)

// 三个参数:元素类型、底层容器类型、比较对象
priority_queue<int,vector<int>,less<int> > q;(less<int>数字大优先级大)
priority_queue<int,vector<int>,greater<int> > q;(less<int>数字小优先级大)

结构体的优先级问题(使用友元类)

struct fruit {
	string name;
	int price;
	//注意:只能重载<,而且优先队列的返回符号与sort的cmp相反
	friend bool operator < (fruit f1,fruit f2) {
		return f1.price < f2.price;
	}
}

注意:使用top函数前必须用empty()判断队列是否为空

  • 常用方法
    • top()
    • push(x)
    • pop()

自定义排序相关:

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue> // prority_queue、queue

using namespace std;

struct Node {
    int num;
    int second;
    Node(int num, int second):num(num), second(second) {}
};

bool operator<(Node x, Node y) {    // 默认(大根堆)重载<符号
    if (x.num != y.num) return x.num < y.num;
    return x.second < y.second;
} 

bool operator>(Node x, Node y) {    // 小根堆重载>符号
    if (x.num != y.num) return x.num > y.num;
    return x.second > y.second;
}

int main()
{
    priority_queue<Node> pq;    // 默认是大根堆(降序),队头元素最大
    priority_queue<Node,vector<Node>, greater<Node>> pq1;
    Node node0(-2,2);
    Node node1(1,2);
    Node node2(-1,2);
    pq.push(node0);
    pq.push(node1);
    pq.push(node2);
    while (!pq.empty()) {
        cout << pq.top().num << " " << pq.top().second << endl;
        pq.pop();
    }
    cout<<"====================="<<endl;
    pq1.push(node0);
    pq1.push(node1);
    pq1.push(node2);
    while (!pq1.empty()) {
        cout << pq1.top().num << " " << pq1.top().second << endl;
        pq1.pop();
    } 
    return 0;
}
// 输出:
//	1 2
//	-1 2
//	-2 2
//	=====================
//	-2 2
//	-1 2
//	1 2

list(双向链表)

  • 头文件及定义
#include <list>			//头文件
list <typename> name;	//使用

访问方式:通过迭代器访问

  • 常用方法
    • push_front()、emplace_front()、push_back()、emplace_back()
    • swap(x,y) # 和其他方法语法有所差异
    • remove(val)、remove_if()
    • unique() # 删除容器中相邻的重复元素,保留一个

forward_list(C11新增,单链表)

效率高是选用 forward_list 而弃用 list 容器最主要的原因,换句话说,只要是 list 容器和 forward_list 容器都能实现的操作,应优先选择 forward_list 容器。

#include <forward_list >		//头文件
forward_list <typename> name;	//使用
  • push_front()、emplace_front()、push_back()、emplace_back()
    • swap(x,y) # 和其他方法语法有所差异
    • remove(val)、remove_if()
    • unique() # 删除容器中相邻的重复元素,保留一个

关联式容器

注:关联式容器都有find方法(pair除外,multiset和multimap需要配合count进行使用)。

set(内部自动有序且去重)

  • 头文件及定义
#include <set>			//头文件
set <typename> name;	//使用

访问方式:只能通过迭代器访问

  • 常用方法
    • insert()、count()、erase()

multiset(允许存在重复数据的set)

  • 头文件及定义
#include <multiset>			//头文件
multiset <typename> name;	//使用

访问方式:只能通过迭代器访问

  • 常用方法
    • insert()、count()、erase()

unordered_set(C11新增)

  • 头文件及定义
#include <unordered_set>		//头文件
unordered_set<typename> name;	//使用

访问方式:只能通过迭代器访问

区别:set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。

unordered_multiset(C11新增)

  • 头文件及定义
 #include <unordered_multiset>		//头文件
unordered_multiset<typename> name;	//使用

访问方式:只能通过迭代器访问
和 unordered_set 容器不同的是,unordered_multiset 容器可以同时存储多个值相同的元素,且这些元素会存储到哈希表中同一个桶(本质就是链表)上。

pair(键值对)

  • 头文件及定义
#include <utility>				//头文件
pair <typename,typename> name;	//使用

访问方式:通过键访问

pair<string,string> pair0;
//插入元素
pair1.first = "key0";
pair1.second = "value0";
pair<string,string> pair1(make_pair("key1","value1"));		//推荐该方式,统一
pair<string,string> pair2(string("key2"),string("value2"));

map

底层实现:红黑树。

  • 头文件及定义
#include <map>					//头文件
map <typename,typename> name;	//使用

访问方式:通过迭代器访问 iter->first,iter->second

map<string,int> m3 = {	// 初始化并赋值,注意键值对之间的对应符号仍是逗号
  {"string",1}, {"sec",2}, {"trd",3}
  };

map<string,string> map;
//插入
map.insert(pair<int,string> (0,"value0"));
map.insert(map<int,string>::value_type (1, "value1"));	//插入 value_type 数据
map['key2'] = value2;

获取最大最小键的方法:

auto it = map.begin();
cout<<"最小键:"<<it->first<<","<<it->second<<end;
auto it = map.end();
it--; 
cout<<"最大键:"<<it->first<<","<<it->second<<endl;
  • 常用方法
    • erase()

unordered_map(C11新增)

unordered_map 容器和 map 容器仅有一点不同,即 map 容器中存储的数据是有序的,而 unordered_map 容器中是无序的。

unordered_multimap(C11新增)

unordered_multimap 容器可以存储多个键相等的键值对,而 unordered_map 容器不行。

algorithm头文件

#include <algorithm>

查找

max(),min(),abs();	//cmath也提供

交换

swap();	//cmath也提供

排序

函数名用法
sort (first, last)对容器或普通数组中 [first, last) 范围内的元素进行排序,默认进行升序排序。
stable_sort (first, last)和 sort() 函数功能相似,不同之处在于,对于 [first, last) 范围内值相同的元素,该函数不会改变它们的相对位置。
partial_sort (first, middle, last)从 [first,last) 范围内,筛选出 muddle-first 个最小的元素并排序存放在 [first,middle) 区间中。
partial_sort_copy (first, last, result_first, result_last)从 [first, last) 范围内筛选出 result_last-result_first 个元素排序并存储到 [result_first, result_last) 指定的范围中。
is_sorted (first, last)检测 [first, last) 范围内是否已经排好序,默认检测是否按升序排序。
is_sorted_until (first, last)和 is_sorted() 函数功能类似,唯一的区别在于,如果 [first, last) 范围的元素没有排好序,则该函数会返回一个指向首个不遵循排序规则的元素的迭代器。
void nth_element (first, nth, last)找到 [first, last) 范围内按照排序规则(默认按照升序排序)应该位于第 nth 个位置处的元素,并将其放置到此位置。同时使该位置左侧的所有元素都比其存放的元素小,该位置右侧的所有元素都比其存放的元素大。
  • 头文件及常用函数
#include <algorithm>

sort(a, a+6);		//默认递增

bool cmp(double a, double b){
	return a > b;
}
bool cmp(node a,node b){
	return a.x > b.x;
}

stable_sort(a,a+6);	//稳定排序
find(vec.begin(),vec.end(),6);//查找函数(一般用于verctor的查找)
//主要实现在容器内查找指定元素,并且这个元素必须是基本数据类型的。查找成功返回一个指向指定元素的迭代器,查找失败返回end迭代器。
vector<int>::iterator result = find( L.begin( ), L.end( ), 6 ); //查找3
if ( result == L.end( ) ) //没找到
    cout << "No" << endl;
 else //找到
    cout << "Yes " <<(*result)<< endl;

后记

此刻感觉只有这些比较重要的了,如果还有的话,在进行补充就可以了。
总结可能不是十分完善,欢迎指出错误或提供建议。

参考网址

C语言中文网

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值