【編程語言】C++ STL 常用函數

作者:LogM

本文原載於 https://segmentfault.com/u/logm/articles ,不允許轉載~

algorithm

#include <algorithm>

min(a, b, comp); //取最小
max(a, b, comp);
min({a,b,c,d}, comp); //initializer_list
max({a,b,c,d}, comp);
*min_element(v.begin(), v.end(), comp);  //數組取最小值
*max_element(v.begin(), v.end(), comp);

swap(a, b);  // 交換
reverse(v.begin(), v.end()); //翻轉

sort(v1.begin(), v1.end(), comp);   //不穩定排序
stable_sort(v1.begin(), v1.end(), comp);     //穩定排序

//comp函數舉例
bool cmp_less(const int& a, const int& b) {
    return a < b;
}

iter = find(v1.begin(), v1.end(), elem);    //查找等於elem的元素
iter = search(v1.begin(), v1.end(), v2.begin(), v2.end());    //在v1中查找是否有區間包含v2,若沒找到,返回v1.end()
lower_bound(v1.begin(), v1.end(), elem);   //數組已排序,返回指向首個不小於elem的迭代器
upper_bound(v1.begin(), v1.end(), elem);   //數組已排序,返回指向首個大於elem的迭代器
binary_search(v1.begin(), v1.end(), elem);  //數組已排序,返回是否找到

迭代器

begin() / end();    //迭代
rbegin() / rend();   //反向迭代
cbegin() / cend();   //const迭代
crbegin() / crend();  //const反向迭代

//冒號遍歷,基於迭代器實現,但遍歷過程中insert和erase將引發無定義的行爲,
//不能修改set和map的key等本身無法修改的元素
for (auto v:vec);    //冒號遍歷(只讀)
for (auto& v:vec);   //冒號遍歷(讀寫)

iter = set1.erase(iter);    //迭代過程中的安全erase

string

#include <string>

string s1("hello");     //與下一行效果相同
string s1 = "hello";
string s1(4, '=');      //生成4個'='組成的字符串
string s1(s2, 0, s2.size());  //拷貝另一個字符串的某個區間初始化

s1.clear();     //清空
s1.size();   //返回字符串長度,與下一行效果相同(不計'\0')
s1.length();
s1.empty();  //是否爲空

s1.c_str();      //返回const char*形式
s1.substr(0, s1.size());     //返回指定區間內的子串,深拷貝
s1.append(s2, 0, s2.size());    //字符串後接另一個字符串的某個區間

to_string(100);     //數值型轉字符串
stoi("100");    //字符串轉整型
stod("0.1");     //字符串轉浮點型

vector

#include <vector>

vector<int> v1 = v2;  //深拷貝構造
vector<int> v1 = {0,1,2,3};  //initializer_list初始化
vector<int> v1(v2.begin(), v2.end());  //vector或array初始化
vector<int> v1(7);  //初始化有7個元素的vector
vector<int> v1(7, 3)    //初始化有7個3的vector
vector<int> v1(r, vector<int>(c, 0))  //初始化r行c列全爲0的矩陣

v1.clear();     //清空
v1.size();   //返回元素數量
v1.empty();  //是否爲空

v1.front();     //訪問第一個元素
v1.back();      //訪問最後一個元素

v1.push_back(100);  //末尾插入元素
v1.pop_back();  //清除末尾元素

iter = v1.insert(v1.begin(), 100);  //在vector最前面插入100
iter = v1.insert(v1.begin(), v2.begin(), v2.end());  //插入另一個數組
iter = v1.erase(v1.begin()+2);  //erase一個數
iter = v1.erase(v1.begin()+2, v1.begin()+5);    //erase一個區間

stack

#include <stack>

s1.clear();     //清空
s1.size();   //返回元素數量
s1.empty();  //是否爲空

s1.top();    //返回棧頂元素

s1.push(100);  //壓棧
s1.pop();  //彈棧

queue/deque

#include <queue>
#include <deque>

q1.clear();     //清空
q1.size();   //返回元素數量
q1.empty();  //是否爲空

q1.front();    //返回第一個元素
q1.back();   //返回最後一個元素

q1.push_front(100);  //首位插入100
q1.push_back(100);  //末位插入100
q1.pop_front();  //彈出第一個元素
q1.pop_back();  //彈出最後一個元素

優先級隊列

//使用堆實現,建堆O(n),插入O(logn),刪除O(logn),查找同vector
#include <queue>

priority_queue<int, vector<int>, less<int>> maxQ;   //大頂堆
priority_queue<int, vector<int>, greater<int>> minQ;    //小頂堆
priority_queue<int> q1(less<int>(), v1);    //用v1初始化大頂堆

q1.clear();     //清空
q1.size();   //返回元素數量
q1.empty();  //是否爲空

q1.top();    //返回堆頂元素

q1.push(100);  //壓入堆
q1.pop();  //彈出堆頂

//自定義比較函數Comp類的寫法
struct CompLess {
    bool operator() (const int a, const int b) {
        return a < b;
    }
};

//另一種建heap的方式
#include <algorithm>
std::make_heap(v.begin(), v.end(), comp);   //建最大堆,v.front()爲最大元素

v.push_back(6);
std::push_heap(v.begin(), v.end());  //其他部分爲最大堆,末尾元素爲新插入,進行上濾

std::pop_heap(v.begin(), v.end(), comp);    //堆頂與堆底交換,然後下濾
v.pop_back()

pair

#include <utility>

pair<int, string> p1(1, "Tom");     //生成一個pair
pair<int, string>(1, "Tom");  //與下兩行效果相同,類型由用戶指定
pair(1, "Tom");     //與上一行效果相同,編譯器判斷變量類型
make_pair(1, "Tom");  //與上一行效果相同,編譯器判斷變量類型
p1.first;
p1.second;

set/multiset

//基於紅黑樹實現,有自動排序,插入O(logn),查找O(logn),刪除O(logn)
//也導致無法直接修改set中的元素,只能先刪除再插入
#include <set>
#include <multiset>

set<int, less<int>> c1(c2);  //深拷貝構造
set<int, less<int>> c1(c2.begin(), c2.end());
set<int, less<int>> c1(c2.begin(), c2.end(), comp);     //迭代器返回的元素依次排序

c1.clear();   //清空
c1.size();   //返回元素數量
c1.empty();  //是否爲空

c1.count(elem);  //返回elem的count,可以用於判斷set中是否有elem
c1.find(elem);   //返回指向elem的迭代器,用"!=c1.end()"判斷是否找到
c1.lower_bound(elem);   //返回指向首個不小於elem的迭代器
c1.upper_bound(elem);   //返回指向首個大於elem的迭代器

c1.insert(elem);    //插入單個elem
c1.insert(c2.begin(), c2.end());    //插入另一個set的某個區間
c1.erase(elem);  //返回被移除的元素的數量
c1.erase(iter);  //清除iter指向的元素
c1.erase(c1.begin()+2, c1.begin()+5);   //清除某個區間

unordered_set/unordered_multiset

//基於哈希表實現,插入O(n),查找O(n),刪除O(n)
//代價佔用內存比set/multiset略大一點點,內部元素不排序
#include <unordered_set>

//大部分函數同set/multiset
//由於內部元素不排序,不能使用lower_bound和upper_bound

map/multimap

//基於紅黑樹實現,依據key自動排序,插入O(logn),查找O(logn),刪除O(logn)
//也導致無法直接修改map中的元素,只能先刪除再插入
#include <map>

map<int, string> m1 = {{2015, "Tom"}, {2016, "Jim"}};   //構造函數

m1.clear();   //清空
m1.size();   //返回元素數量
m1.empty();  //是否爲空

m1.at[2015] = "Tom";    //取值,會檢查key是否存在
m1[2015] = "Tom";   //若key存在則修改value,若不存在則創建

m1.count(key);     //返回相應key的count,可以用於判斷map中是否存在該key
iter = m1.find(key);   //返回指向key的迭代器,用"!=m1.end()"判斷是否找到
c1.lower_bound(key);   //返回指向首個不小於key的迭代器
c1.upper_bound(key);   //返回指向首個大於key的迭代器

m1.insert(make_pair(2015, "Tom"));  //使用pair插入
m1.insert(pair<int, string>(2015, "Tom"));
m1.insert({2015, "Tom"});   //initializer_list插入
m1.erase(key);  //返回被移除的元素的數量
m1.erase(iter);  //清除iter指向的元素
m1.erase(m1.begin()+2, m1.begin()+5);   //清除某個區間

unordered_map/unordered_multimap

//基於哈希表實現,插入O(n),查找O(n),刪除O(n)
//代價佔用內存比map/multimap略大一點點,內部元素不排序
#include <unordered_map>

//大部分函數同map/multimap
//由於內部元素不排序,不能使用lower_bound和upper_bound

list

list<int> l1 = l2;  //深拷貝構造
list<int> l1 = {0,1,2,3};  //initializer_list初始化
list<int> l1(l2.begin(), l2.end());  
list<int> l1(7);  //初始化有7個元素的list
list<int> l1(7, 3)    //初始化有7個3的list

l1.clear();     //清空
l1.size();   //返回元素數量
l1.empty();  //是否爲空

l1.front();     //訪問第一個元素
l1.back();      //訪問最後一個元素

l1.push_back(100);  //末尾插入元素
l1.pop_back();  //清除末尾元素

iter = l1.insert(l1.begin(), 100);  //在vector最前面插入100
iter = l1.insert(l1.begin(), l2.begin(), l2.end());  //插入另一個數組
iter = l1.erase(l1.begin()+2);  //erase一個數
iter = l1.erase(l1.begin()+2, l1.begin()+5);    //erase一個區間

基礎輸入輸出

# include<string>
std::string str;
std::getline(std::cin, str);  //會把'\n'去除
std::getline(std::cin, str, ' ');  //設置分隔符,此時將空格視爲一行的結束,'\n'會被讀入
/*
立即在空白符分隔輸入後使用時,例如在 int n; std::cin >> n; 後, getline 會用 operator>> 消耗掉留在輸入流上的換行符,並立即返回。
常用解決方案是在切換到面向行輸入前,用 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 忽略輸入行上所有剩下的字符。
*/

匿名函數

sort(v.begin(), v.end(),
        [](const int& a, const int& b) {
            return a < b;
        });
發佈了52 篇原創文章 · 獲贊 19 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章