I use Python in my work, and rarely need C++. So I need to compile this C++ cheatsheet for common STL containers/adapters, just in case I need them.
vector#
- Define a 1D vector:
vector<int> arr = {1, 2, 3}; - Define a 2D vector:
vector<vector<int>> mat = {{1, 2, 3}, {4, 5}}; - Define a 2D vector of size 3x4:
vector<vector<int> > mat(3, vector<int>(4, 0)); - Add an element:
arr.push_back(2); - Insert an element:
arr.insert(arr.begin(), -1); - Insert another vector:
vector<int> another = {1, 2, 3}; arr.insert(arr.begin(), another.begin(), another.end()); - Check its size:
cout << arr.size(); - Check if vector is empty:
cout << arr.empty(); - Slice a vector, i.e., get a sub-vector from an existing vector:
vector<int> arr(10, 1); vector<int> new_vec(arr.begin(), arr.begin()+3);(this is end-exclusive, so the resulting vector has 3 elements) - Sort a vector:
- In ascending order (the default):
std::sort(arr.begin(), arr.end()); - In descending order (we need to use custom compare function):
std::sort(arr.begin(), arr.end(), std::greater<int>());
- In ascending order (the default):
Ref:
- Best way to extract a sub-vector from a vector?: https://stackoverflow.com/q/421573/6064933
string#
- Define a string:
string myStr = "hello"; - Get string size:
myStr.size() - Get sub-string:
myStr.substr(0, 2)(Get the substring starting at index 0 and with length 2, end-exclusive style) - Get sub-string:
myStr.substr(1)(Get substring starting at index 1 till the end) - Check if string is empty:
myStr.empty(); - Generate a string with
nsame characterch:string(n, ch); - Reverse a string: use
std::reverse,std::reverse(myStr.begin(), myStr.end()).
Ref:
- Repeat string n times: https://stackoverflow.com/q/166630/6064933
set (works like a Python set)#
set in C++ is typically implemented using balanced binary search tree.
- Define a set:
set<int> x = {1, 2, 3}; - Add an element:
x.insert(5); - Check size:
x.size() - Check if set is empty:
x.empty(); - Check if set contains a key:
x.find(2) != x.end();orx.count(2) != 0 - Initialize set from a vector of int:
vector<int> arr = {1, 2, 1, 3}; set<int> my_set(arr.begin(), arr.end());
There is also unordered_set, which is different from set:
- The underlying implementation for
setis binary search tree (BST), while the underlying implementation forunordered_setis hash table. - The element in
setis sorted so that their order is guaranteed, while forunordered_set, there is no guarantee for the element order. setrequires less memory thanunordered_set(unordered_sethas to store a hash table).- Search time is at most
O(log(n))forset, while forunordered_set, the search time is on averageO(1), but may beO(n)in worst case (highly unlikely)
map (works like a Python dict)#
Typically implemented using balanced binary search tree.
Define an empty map:
map<int, string> items;Define a constant map:
map<int, string> num2str = {{1, "ab"}, {2, "cd"}, {3, "ef"}};Add an element:
items.insert({1, "apple"});oritems[1] = "apple";Remove an element:
items.erase("apple");Access a key (no check):
cout << items[1] << endl;(we have to make sure the key exists, otherwise it will be inserted silently)Access a key (with check):
cout << items.at(4);(will error out)Show map element key and value:
for (auto item: items){ cout << item.first << " " << item.second << endl; }
ref:
- define constant map: https://stackoverflow.com/a/8688615/6064933
- Check if map contains a key:
bool has_key = items.find(2) != items.end();oritems.count(2) != 0
There is also unordered_map. The different between map and unordered_map is similar to the difference between set and unordered_set.
So I will not elaborate on this.
Note that when map is defined using the const modifier, you can not access map element with operator [],
since it is possible to alter map value when accessing map element like this,
check this post for more details.
queue#
Queue is a data structure that provides FIFO (first in first out) feature. Element that is added first will also be removed first.
- Get queue size:
queue<int> q; cout << q.size() << endl; - Check if queue is empty: use
q.empty()orq.size() == 0 - Get front element of queue:
cout << q.front() << endl; - Add element to queue:
q.push(4); - Pop up front element:
q.pop();
stack#
Stack is the opposite of queue. It provides a LIFO (last in first out) data structure. Element that is added last will be removed first.
- Get stack size:
stack<int> s; cout << s.size() << endl; - Check if stack is empty:
s.empty()ors.size() == 0 - Get top element from stack:
cout << s.top() << endl;(note that getting top element when stack is empty leads to errors!) - Add element to stack:
s.push(1); - Pop up element from stack:
s.pop();
tuple#
Tuple can be used to different types of data.
- Create a tuple:
std::make_tuple("abc", 2, 3); - Get tuple element:
std:get<0>(some_tuple);(get first element, really weird and unintuitive syntax!)
pair#
Pair can be used to hold two different data types conveniently.
- Create a pair:
pair<int, string> my_pair = std::make_pair(2, "abc") - Get pair element:
my_pair.firstandmy_pair.second
Ref:
- Get tuple element: https://stackoverflow.com/q/32606464/6064933
References#
- Sort vector in descending order: https://stackoverflow.com/q/9025084/6064933
- Why would anyone use set instead of unordered_set?: https://stackoverflow.com/q/1349734/6064933
- How to choose between map and unordered_map?: https://stackoverflow.com/q/13799593/6064933
- Is there any advantage of using map over unordered_map in case of trivial keys?: https://stackoverflow.com/q/2196995/6064933