C++ 知识总结

C++常用知识点

l   count函数用以统计key值在unordered_map中出现的次数。实际上,c++ unordered_map不允许有重复的key。因此,如果key存在,则count返回1,如果不存在,则count返回0.  Eg:unordered_map<int, int> water; if(water.count(r)){…}

unordered_map关联容器的常用方法

       find() 如果key存在,则find返回key对应的迭代器,如果key不存在,则find返回unordered_map::end。因此可以通过map.find(key) == map.end()

    emplace()向容器中添加新键值对,效率比 insert() 方法高。

Eg:vector<vector<int>>& connections 

link_map[conn[0]].emplace(conn[1]);

 

unordered_set关联容器的常用方法

       erase()删除指定元素

//删除 set 容器中值为 val 的元素, 返回成功删除元素的个数

size_type erase (const value_type& val);

//删除 position 迭代器指向的元素,返回值是迭代器,指向set容器中删除之后的第一个元素

iterator  erase (const_iterator position);

//删除 [first,last) 区间内的所有元素,返回值是迭代器,指向set容器中删除之后的第一个元素

iterator  erase (const_iterator first, const_iterator last);

eg: unordered_set<string> origin;  origin.erase(word.substr(k));

       创建unordered_set关联容器,创建空的容器/初始化容器/赋值拷贝 初始化容器;

1) 通过调用 unordered_set 模板类的默认构造函数,可以创建空的 unordered_set 容器。比如:

std::unordered_set<std::string> uset;

2) 当然,在创建 unordered_set 容器的同时,可以完成初始化操作。比如:

std::unordered_set<std::string> uset{ "http://c.biancheng.net/c/",

                                      "http://c.biancheng.net/java/",

                                      "http://c.biancheng.net/linux/" };

3) 还可以调用 unordered_set 模板中提供的复制(拷贝)构造函数,将现有 unordered_set 容器中存储的元素全部用于为新建 unordered_set 容器初始化。

std::unordered_set<std::string> uset2(uset);

4) 当然,如果不想全部拷贝,可以使用 unordered_set 类模板提供的迭代器

std::unordered_set<std::string> uset2(++uset.begin(),uset.end());

eg: vector<string>& words; unordered_set<string> good(words.begin(), words.end());

 

string类型的常用方法

       substr() 对象的子串string substr(int m = 0,int n = npos) const; substr 成员函数可以用于求子串 (n, m),原型如下:调用时,如果省略 m 或 m 超过了字符串的长度,则求出来的子串就是从下标 n 开始一直到字符串结束的部分。例如:

string s1 = "this is ok";

string s2 = s1.substr(2, 4);  // s2 = "is i"

s2 = s1.substr(2);  // s2 = "is is ok"

     assign() 和 对string对象赋值,

string s1(“Hello”)   string s2;  s2.assign(s1);

s2.assign(s1, 1, 2); // s2 = “el”, 即s1的子串(1,2)

s2.assign(4, ‘k’);   //s2 = “kkkk”

s2.assin(“abcde”,2,3); //s2 = “cde”,即abcde的子串(2,3)

         append() 字符串连接。----用来向字符串后面添加内容。append 成员函数返回对象自身的引用。

string s1("123"), s2("abc");

s1.append(s2);  // s1 = "123abc"

s1.append(s2, 1, 2);  // s1 = "123abcbc"

s1.append(3, 'K');  // s1 = "123abcbcKKK"

s1.append("ABCDE", 2, 3);  // s1 = "123abcbcKKKCDE",添加 "ABCDE" 的子串(2, 3)

    compare() 字符串比较。返回值,小于0 表示当前字符串小,等于0表示字符相等,大于0表示另外一个字符小。

string s1("hello"), s2("hello, world");

int n = s1.compare(s2);

n = s1.compare(1, 2, s2, 0, 3);  //比较s1的子串 (1,2) 和s2的子串 (0,3)

n = s1.compare(0, 2, s2);  // 比较s1的子串 (0,2) 和 s2

n = s1.compare("Hello");

n = s1.compare(1, 2, "Hello");  //比较 s1 的子串(1,2)和"Hello”

n = s1.compare(1, 2, "Hello", 1, 2);  //比较 s1 的子串(1,2)和 "Hello" 的子串(1,2)

find()从前往后查找子串或字符出现的位置。rfind:从后往前查找子串或字符出现的位置。

find_first_of:从前往后查找何处出现另一个字符串中包含的字符。s1.find_first_of("abc");  //查找s1中第一次出现"abc"中任一字符的位置

find_last_of:从后往前查找何处出现另一个字符串中包含的字符。

find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。

find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。

    string s1("Source Code");

    int n;

    if ((n = s1.find('u')) != string::npos) //查找 u 出现的位置

        cout << "1) " << n << "," << s1.substr(n) << endl;

    //输出 l)2,urce Code

    if ((n = s1.find("Source", 3)) == string::npos)

        //从下标3开始查找"Source",找不到

        cout << "2) " << "Not Found" << endl;  //输出 2) Not Found

    if ((n = s1.find("Co")) != string::npos)

        //查找子串"Co"。能找到,返回"Co"的位置

        cout << "3) " << n << ", " << s1.substr(n) << endl;

    //输出 3) 7, Code

    if ((n = s1.find_first_of("ceo")) != string::npos)

        //查找第一次出现或 'c'、'e'或'o'的位置

        cout << "4) " << n << ", " << s1.substr(n) << endl;

    //输出 4) l, ource Code

    if ((n = s1.find_last_of('e')) != string::npos)

        //查找最后一个 'e' 的位置

        cout << "5) " << n << ", " << s1.substr(n) << endl;  //输出 5) 10, e

    if ((n = s1.find_first_not_of("eou", 1)) != string::npos)

        //从下标1开始查找第一次出现非 'e'、'o' 或 'u' 字符的位置

        cout << "6) " << n << ", " << s1.substr(n) << endl;

    //输出 6) 3, rce Code

    replace()替换子串。对 string 对象中的子串进行替换,返回值为对象自身的引用。

string s1("Real Steel");

s1.replace(1, 3, "123456", 2, 4);  //用 "123456" 的子串第2个字符开始4个字符 替换 s1 的子串从位置1的字符后的3个字符。

cout << s1 << endl;  //输出 R3456 Steel

string s2("Harry Potter");

s2.replace(2, 3, 5, '0');  //用 5 个 '0' 替换子串(2,3)

cout << s2 << endl;  //输出 HaOOOOO Potter

int n = s2.find("OOOOO");  //查找子串 "00000" 的位置,n=2

s2.replace(n, 5, "XXX");  //将子串(n,5)替换为"XXX"

cout << s2 < < endl;  //输出 HaXXX Potter

  insert()插入子字符串。insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。例如:

string s1("Limitless"), s2("00");

s1.insert(2, "123");  //在下标 2 处插入字符串"123",s1 = "Li123mitless"

s1.insert(3, s2);  //在下标 2 处插入 s2 , s1 = "Li10023mitless"

s1.insert(3, 5, 'X');  //在下标 3 处插入 5 个 'X',s1 = "Li1XXXXX0023mitless"

  erase()删除子串。删除 string 对象中的子串,返回值为对象自身的引用。

string s1("Real Steel");

s1.erase(1, 3);  //删除子串(1, 3),此后 s1 = "R Steel"

s1.erase(5);  //删除下标5及其后面的所有字符,此后 s1 = "R Ste"

 

lower_bound( )和upper_bound( )常见用法-----

       在从小到大的排序数组中, lower_bound( begin,end,num):从容器的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。 upper_bound( begin,end,num):从容器的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

Eg int lc =lower_bound(C.begin(),C.end(), requirements[i][0])-C.begin();

 

set集合常用方法----

insert() 用于在集合中插入元素,且元素键在集合中是唯一的。

//普通引用方式传参

pair<iterator,bool> insert (const value_type& val);

eg: pars.insert(getRoot(i));

//以普通引用的方式传递 val 值

iterator insert (const_iterator position, const value_type& val);

eg: set<int> s; auto itr = s.insert(s.begin(), 1); itr = s.insert(itr, 4);

vector 向量容器的常用方法---

vector<double> values; //创建一个double类型元素的vector容器;

二维数组初始化

vector<vector<int>> sum(row+1, vector<int>(3,0)); 注: sum.size() 是行数。

 

values.reserve(20); //增加容器的容量;

values.resize(n);//改变实际元素的个数n

values.push_back(1.0);//在序列的尾部添加一个元素;

values.pop_back(2.0);//移除序列尾部的元素

常用算法

       sort() 函数,针对区间[L, R)

void sort (RandomAccessIterator first, RandomAccessIterator last);

//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

//以函数对象的方式实现自定义排序规则

class mycomp2 {

public:

    bool operator() (int i, int j) {

        return (i < j);

    }

};

vector<int> myvector{ 32, 71, 12, 45, 26, 80, 53, 33 };

sort(myvector.begin(), myvector.begin() + 4); //(12 32 45 71) 26 80 53 33

sort(myvector.begin(), myvector.begin() + 4, greater<int>()); //(71 45 32 12) 26 80 53 33

sort(myvector.begin(), myvector.end(), mycomp2());//12 26 32 33 45 53 71 80

   stable_sort() 函数,针对区间[L, R)

当指定范围内包含多个相等的元素时,完成排序且可以保证相等元素的相对位置。

       partial_sort()排序函数

partial_sort() 函数会以交换元素存储位置的方式实现部分排序的。具体来说,partial_sort() 会将 [first, last) 范围内最小(或最大)的 middle-first 个元素移动到 [first, middle) 区域中,并对这部分元素做升序(或降序)排序。只适用于 array、vector、deque 这 3 个容器。容器中存储的元素类型必须支持 <小于运算符;

std::vector<int> myvector{ 3,2,5,4,1,6,9,7};

//以默认的升序排序作为排序规则,将 myvector 中最小的 4 个元素移动到开头位置并排好序

std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end()); // 1 2 3 4 5 6 9 7

 // 以指定的 mycomp2 作为排序规则,将 myvector 中最大的 4 个元素移动到开头位置并排好序

std::partial_sort(myvector.begin(), myvector.begin() + 4, myvector.end(), mycomp2()); //9 7 6 5 1 2 3 4

       partial_sort_copy() 函数

partial_sort_copy() 函数会将 [first, last) 范围内最小(或最大)的 result_last-result_first 个元素复制到 [result_first, result_last) 区域中,并对该区域的元素做升序(或降序)排序。

int myints[5] = { 0 };

std::list<int> mylist{ 3,2,5,4,1,6,9,7 };

//按照默认的排序规则进行部分排序

std::partial_sort_copy(mylist.begin(), mylist.end(), myints, myints + 5); //1 2 3 4 5

//以自定义的 mycomp2 作为排序规则,进行部分排序

std::partial_sort_copy(mylist.begin(), mylist.end(), myints, myints + 5, mycomp2());//9 7 6 5 4

merge() 函数用于将 2 个有序序列合并为 1 个有序序列

merge() 函数用于将 2 个有序序列合并为 1 个有序序列

//first 和 second 数组中各存有 1 个有序序列

int first[] = { 5,10,15,20,25 };

int second[] = { 7,17,27,37,47,57 };

//用于存储新的有序序列

vector<int> myvector(11);

//将 [first,first+5) 和 [second,second+6) 合并为 1 个有序序列,并存储到 myvector 容器中。

merge(first, first + 5, second, second + 6, myvector.begin());

//myvector  5 7 10 15 17 20 25 27 37 47 57

inplace_merge()函数

当 2 个有序序列存储在同一个数组或容器中时,将它们合并为 1 个有序序列

int first[] = { 5,10,15,20,25,7,17,27,37,47,57 };

//将 [first,first+5) 和 [first+5,first+11) 合并为 1 个有序序列。

inplace_merge(first, first + 5,first +11)

       find() 函数

用于在指定范围内查找和目标元素值相等的第一个元素。[first, last) 用于指定该函数的查找范围;val 为要查找的目标元素。该函数适用于所有的序列式容器。

char stl[] ="http://c.biancheng.net/stl/";

char * p = find(stl, stl + strlen(stl), 'c');

//判断是否查找成功

if (p != stl + strlen(stl)) {

    cout << p << endl;

}

//find() 函数作用于容器

std::vector<int> myvector{ 10,20,30,40,50 };

std::vector<int>::iterator it;

it = find(myvector.begin(), myvector.end(), 30);

if (it != myvector.end())

       find_if() 函数

会根据指定的查找规则,在指定区域内查找第一个符合该函数要求(使函数返回 true)的元素。

vector<int> myvector{ 4,2,3,1,5 };

//调用 find_if() 函数,并以 IsOdd() 一元谓词函数作为查找规则

vector<int>::iterator it = find_if(myvector.begin(), myvector.end(), mycomp2());//*it = 3

       find_if_not()函数

find_if_not() 函数也适用于所有的容器,包括所有序列式容器和关联式容器。该函数也会返回一个输入迭代器,当 find_if_not() 函数查找成功时,该迭代器指向的是查找到的那个元素;反之,如果查找失败,该迭代器的指向和 last 迭代器相同。

//自定义一元谓词函数

bool mycomp(int i) {

    return ((i % 2) == 1);

}

vector<int> myvector{4,2,3,1,5};

//调用 find_if() 函数,并以 mycomp() 一元谓词函数作为查找规则

vector<int>::iterator it = find_if_not(myvector.begin(), myvector.end(), mycomp);// 4

       find_end() 函数

用于在序列 A 中查找序列 B 最后一次出现的位置。

//以函数对象的形式定义一个匹配规则

class mycomp2 {

public:

    bool operator()(const int& i, const int& j) {

        return (i%j == 0);

    }

};

 vector<int> myvector{ 1,2,3,4,8,12,18,1,2,3 };

int myarr[] = { 1,2,3 };

//调用第一种语法格式

vector<int>::iterator it = find_end(myvector.begin(), myvector.end(), myarr, myarr + 3);

cout << "最后一个{1,2,3}的起始位置为:" << it - myvector.begin() << ",*it = " << *it << endl;

int myarr2[] = { 2,4,6 };

//调用第二种语法格式

it = find_end(myvector.begin(), myvector.end(), myarr2, myarr2 + 3, mycomp2());

cout << "最后一个{2,3,4}的起始位置为:" << it - myvector.begin() << ",*it = " << *it;

       find_first_of()函数

用于在 [first1, last1) 范围内查找和 [first2, last2) 中任何元素相匹配的第一个元素。如果匹配成功,该函数会返回一个指向该元素的输入迭代器;反之,则返回一个和 last1 迭代器指向相同的输入迭代器。

l  for 遍历循环表达式

for(auto x : range)

//创建拷贝,无法修改range中的元素

for(auto& x : range)

//可以修改range中的元素,但一般用以下这种

for(auto&& x : range)

for(const auto & x : range)

//只读range中的元素

l  iota 递增序列填充  

vector<int> ivec(10);

iota(ivec.begin(), ivec.end(), 0);

//输出 0 1 2 3 4 5 6 7 8 9 

 

posted @ 2020-10-23 17:43  繁星的夜空2012  阅读(21)  评论(0编辑  收藏  举报