C/C++教程

C++STL笔记

本文主要是介绍C++STL笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

STL学习笔记

  • 参考文档:
    1. https://cplusplus.com/reference/
    2. https://zh.cppreference.com/w/首页
    3. https://docs.microsoft.com/en-us/cpp/standard-library/cpp-standard-library-reference?view=msvc-170
    4. https://github.com/huihut/interview

总体总结

  • 容器分类
  • 容器复合情况

String

  • https://cplusplus.com/reference/string/
    本质:
  • string是C++风格的字符串,而string本质上是一个类
    string和char * 区别:
  • char * 是一个指针
  • string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。

特点:
string 类内部封装了很多成员方法

例如:查找find,拷贝copy,删除delete 替换replace,插入insert

string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责

构造函数

  1. string(); //创建一个空的字符串 例如: string str;
    string(const char* s); //使用字符串s初始化
  2. string(const string& str); //使用一个string对象初始化另一个string对象
  3. string(int n, char c); //使用n个字符c初始化
  • 示例
// string constructor
#include <iostream>
#include <string>

int main ()
{
  std::string s0 ("Initial string");

  // constructors used in the same order as described above:
  std::string s1;
  std::string s2 (s0);
  std::string s3 (s0, 8, 3);
  std::string s4 ("A character sequence");
  std::string s5 ("Another character sequence", 12);
  std::string s6a (10, 'x');
  std::string s6b (10, 42);      // 42 is the ASCII code for '*'
  std::string s7 (s0.begin(), s0.begin()+7);

  std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
  std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6a: " << s6a;
  std::cout << "\ns6b: " << s6b << "\ns7: " << s7 << '\n';
  return 0;
}

//Output:
//s1: 
//s2: Initial string
//s3: str
//s4: A character sequence
//s5: Another char
//s6a: xxxxxxxxxx
//s6b: **********
//s7: Initial

赋值操作

  1. string& operator=(const char* s); //char*类型字符串 赋值给当前的字符串
  2. string& operator=(const string &s); //把字符串s赋给当前的字符串
  3. string& operator=(char c); //字符赋值给当前的字符串
  • 示例
// string assigning
#include <iostream>
#include <string>

int main ()
{
  std::string str1, str2, str3;
  str1 = "Test string: ";   // c-string
  str2 = 'x';               // single character
  str3 = str1 + str2;       // string

  std::cout << str3  << '\n';
  return 0;
}

//Output:
//Test string: x
  1. string& assign(const char *s); //把字符串s赋给当前的字符串
  2. string& assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串
  3. string& assign(const string &s); //把字符串s赋给当前字符串
  4. string& assign(int n, char c); //用n个字符c赋给当前字符串
  • 示例
// string::assign
#include <iostream>
#include <string>

int main ()
{
  std::string str;
  std::string base="The quick brown fox jumps over a lazy dog.";

  // used in the same order as described above:

  str.assign(base);
  std::cout << str << '\n';

  str.assign(base,10,9);
  std::cout << str << '\n';         // "brown fox"

  str.assign("pangrams are cool",7);
  std::cout << str << '\n';         // "pangram"

  str.assign("c-string");
  std::cout << str << '\n';         // "c-string"

  str.assign(10,'*');
  std::cout << str << '\n';         // "**********"

  str.assign<int>(10,0x2D);
  std::cout << str << '\n';         // "----------"

  str.assign(base.begin()+16,base.end()-12);
  std::cout << str << '\n';         // "fox jumps over"

  return 0;
}

//Output:
//The quick brown fox jumps over a lazy dog.
//brown fox
//pangram
//c-string
//**********
//----------
//fox jumps over

字符串拼接

  1. string& operator+=(const char* str); //重载+=操作符
  2. string& operator+=(const char c); //重载+=操作符
  3. string& operator+=(const string& str); //重载+=操作符
  • 示例
// string::operator+=
#include <iostream>
#include <string>

int main ()
{
  std::string name ("John");
  std::string family ("Smith");
  name += " K. ";         // c-string
  name += family;         // string
  name += '\n';           // character

  std::cout << name;
  return 0;
}

//Output:
//John K. Smith
  1. string& append(const char *s); //把字符串s连接到当前字符串结尾
  2. string& append(const char *s, int n); //把字符串s的前n个字符连接到当前字符串结尾
  3. string& append(const string &s); //同operator+=(const string& str)
  4. string& append(const string &s, int pos, int n);//字符串s中从pos开始的n个字符连接到字符串结尾
  • 示例
// appending to string
#include <iostream>
#include <string>

int main ()
{
  std::string str;
  std::string str2="Writing ";
  std::string str3="print 10 and then 5 more";

  // used in the same order as described above:
  str.append(str2);                       // "Writing "
  str.append(str3,6,3);                   // "10 "
  str.append("dots are cool",5);          // "dots "
  str.append("here: ");                   // "here: "
  str.append(10u,'.');                    // ".........."
  str.append(str3.begin()+8,str3.end());  // " and then 5 more"
  str.append<int>(5,0x2E);                // "....."

  std::cout << str << '\n';
  return 0;
}

//Output:
//Writing 10 dots here: .......... and then 5 more.....

string查找和替换

  • 查找:查找指定字符串是否存在
  • 替换:在指定的位置替换字符串
  1. int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
  2. int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
  3. int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
  4. int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
  • 示例
// string::find
#include <iostream>       // std::cout
#include <string>         // std::string

int main ()
{
  std::string str ("There are two needles in this haystack with needles.");
  std::string str2 ("needle");

  // different member versions of find in the same order as above:
  std::size_t found = str.find(str2);
  if (found!=std::string::npos)
    std::cout << "first 'needle' found at: " << found << '\n';

  found=str.find("needles are small",found+1,6);
  if (found!=std::string::npos)
    std::cout << "second 'needle' found at: " << found << '\n';

  found=str.find("haystack");
  if (found!=std::string::npos)
    std::cout << "'haystack' also found at: " << found << '\n';

  found=str.find('.');
  if (found!=std::string::npos)
    std::cout << "Period found at: " << found << '\n';

  // let's replace the first needle:
  str.replace(str.find(str2),str2.length(),"preposition");
  std::cout << str << '\n';

  return 0;
}

//Notice how parameter pos is used to search for a second instance of the same search string. Output:
//first 'needle' found at: 14
//second 'needle' found at: 44
//'haystack' also found at: 30
//Period found at: 51
//There are two prepositions in this haystack with needles
  1. int rfind(const string& str, int pos = npos) const; //查找str最后一次位置,从pos开始查找
  2. int rfind(const char* s, int pos = npos) const; //查找s最后一次出现位置,从pos开始查找
  3. int rfind(const char* s, int pos, int n) const; //从pos查找s的前n个字符最后一次位置
  4. int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
  • 示例:
// string::rfind
#include <iostream>
#include <string>
#include <cstddef>

int main ()
{
  std::string str ("The sixth sick sheik's sixth sheep's sick.");
  std::string key ("sixth");

  std::size_t found = str.rfind(key);
  if (found!=std::string::npos)
    str.replace (found,key.length(),"seventh");

  std::cout << str << '\n';

  return 0;
}

// Output
// The sixth sick sheik's seventh sheep's sick.
  1. string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
  2. string& replace(int pos, int n,const char* s); //替换从pos开始的n个字符为字符串s
  • 示例
// replacing in a string
#include <iostream>
#include <string>

int main ()
{
  std::string base="this is a test string.";
  std::string str2="n example";
  std::string str3="sample phrase";
  std::string str4="useful.";

  // replace signatures used in the same order as described above:

  // Using positions:                 0123456789*123456789*12345
  std::string str=base;           // "this is a test string."
  str.replace(9,5,str2);          // "this is an example string." (1)
  str.replace(19,6,str3,7,6);     // "this is an example phrase." (2)
  str.replace(8,10,"just a");     // "this is just a phrase."     (3)
  str.replace(8,6,"a shorty",7);  // "this is a short phrase."    (4)
  str.replace(22,1,3,'!');        // "this is a short phrase!!!"  (5)

  // Using iterators:                                               0123456789*123456789*
  str.replace(str.begin(),str.end()-3,str3);                    // "sample phrase!!!"      (1)
  str.replace(str.begin(),str.begin()+6,"replace");             // "replace phrase!!!"     (3)
  str.replace(str.begin()+8,str.begin()+14,"is coolness",7);    // "replace is cool!!!"    (4)
  str.replace(str.begin()+12,str.end()-4,4,'o');                // "replace is cooool!!!"  (5)
  str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful."    (6)
  std::cout << str << '\n';
  return 0;
}

// Output
// replace is useful.

字符串比较

比较方式:

  • 字符串比较是按字符的ASCII码进行对比
    = 返回 0
    > 返回 1
    < 返回 -1
  1. int compare(const string &s) const; //与字符串s比较
  2. int compare(const char *s) const; //与字符串s比较
  • 示例
// comparing apples with apples
#include <iostream>
#include <string>

int main ()
{
  std::string str1 ("green apple");
  std::string str2 ("red apple");

  if (str1.compare(str2) != 0)
    std::cout << str1 << " is not " << str2 << '\n';

  if (str1.compare(6,5,"apple") == 0)
    std::cout << "still, " << str1 << " is an apple\n";

  if (str2.compare(str2.size()-5,5,"apple") == 0)
    std::cout << "and " << str2 << " is also an apple\n";

  if (str1.compare(6,5,str2,4,5) == 0)
    std::cout << "therefore, both are apples\n";

  return 0;
}

//Output:
//green apple is not red apple
//still, green apple is an apple
//and red apple is also an apple
//therefore, both are apples

String字符串存取

  1. char& operator[](int n); //通过[]方式取字符
  2. char& at(int n); //通过at方法获取字符
  3. back
  4. front

String插入和删除

  1. string& insert(int pos, const char* s); //插入字符串
  2. string& insert(int pos, const string& str); //插入字符串
  3. string& insert(int pos, int n, char c); //在指定位置插入n个字符c
  • 示例
// inserting into a string
#include <iostream>
#include <string>

int main ()
{
  std::string str="to be question";
  std::string str2="the ";
  std::string str3="or not to be";
  std::string::iterator it;

  // used in the same order as described above:
  str.insert(6,str2);                 // to be (the )question
  str.insert(6,str3,3,4);             // to be (not )the question
  str.insert(10,"that is cool",8);    // to be not (that is )the question
  str.insert(10,"to be ");            // to be not (to be )that is the question
  str.insert(15,1,':');               // to be not to be(:) that is the question
  it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
  str.insert (str.end(),3,'.');       // to be, not to be: that is the question(...)
  str.insert (it+2,str3.begin(),str3.begin()+3); // (or )

  std::cout << str << '\n';
  return 0;
}

//Output:
//to be, or not to be: that is the question...
  1. string& erase(int pos, int n = npos); //删除从Pos开始的n个字符
  • 示例
// string::erase
#include <iostream>
#include <string>

int main ()
{
  std::string str ("This is an example sentence.");
  std::cout << str << '\n';
                                           // "This is an example sentence."
  str.erase (10,8);                        //            ^^^^^^^^
  std::cout << str << '\n';
                                           // "This is an sentence."
  str.erase (str.begin()+9);               //           ^
  std::cout << str << '\n';
                                           // "This is a sentence."
  str.erase (str.begin()+5, str.end()-9);  //       ^^^^^
  std::cout << str << '\n';
                                           // "This sentence."
  return 0;
}

//Output:
//This is an example sentence.
//This is an sentence.
//This is a sentence.
//This sentence.
  1. push_back
  2. swap
  3. pop_back

String子串

  • 从字符串中获取想要的子串
  1. string substr(int pos = 0, int n = npos) const; //返回由pos开始的n个字符组成的字符串
  • 示例
// string::substr
#include <iostream>
#include <string>

int main ()
{
  std::string str="We think in generalities, but we live in details.";
                                           // (quoting Alfred N. Whitehead)

  std::string str2 = str.substr (3,5);     // "think"

  std::size_t pos = str.find("live");      // position of "live" in str

  std::string str3 = str.substr (pos);     // get from "live" to the end

  std::cout << str2 << ' ' << str3 << '\n';

  return 0;
}

//Output:
//think live in details

vector

参考链接:

  1. https://cplusplus.com/reference/vector/vector/
  2. https://docs.microsoft.com/en-us/cpp/standard-library/vector-class?view=msvc-170

vector与普通数组区别:

  • 不同之处在于数组是静态空间,而vector可以动态扩展

Requirements

Header: <vector>
Namespace std

构造函数

// constructing vectors
#include <iostream>
#include <vector>

int main ()
{
  // constructors used in the same order as described above:
  std::vector<int> first;                                // 默认构造函数
  std::vector<int> second (4,100);                       // 构造函数将n个elem拷贝给本身
  std::vector<int> third (second.begin(),second.end());  // 将v[begin(), end())区间中的元素拷贝给本身。
  std::vector<int> fourth (third);                       // 拷贝构造函数

  // the iterator constructor can also be used to construct from arrays:
  int myints[] = {16,2,77,29};
  std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  std::cout << "The contents of fifth are:";
  for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

iterators

begin  // Return iterator to beginning
end  // Return iterator to end
rbegin  // Return reverse iterator to reverse beginning
rend  // Return reverse iterator to reverse end
cbegin  // Return const_iterator to beginning
cend  // Return const_iterator to end
crbegin  // Return const_reverse_iterator to reverse beginning
crend  // Return const_reverse_iterator to reverse end

vector容量和大小

  • size: 返回容器中元素的个数
  • empyt: 判断容器是否为空 空返回true
  • capacity: 容器的容量
  • void resize (size_type n);: 重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
    void resize (size_type n, const value_type& val);: 重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
  • max_size: 容器能够装下的 maximum number of elements
  • reserve: 减少vector在动态扩展容量时的扩展次数. reserve(int len);,容器预留len个元素长度,预留位置不初始化,元素不可访问。

元素访问

  • operator[]; //返回索引idx所指的数据
  • at(int idx); //返回索引idx所指的数据
  • front(); //返回容器中第一个数据元素
  • back(); //返回容器中最后一个数据元素
  • value_type* data() noexcept; : 返回指向容器中第一个元素的指针,因为vector容器内存是连续的所以可以使用p[]访问

元素更改(赋值/插入/删除/互换元素)

  • vector& operator=(const vector &vec);//重载等号操作符
    1. 示例:
copy (1)	vector& operator= (const vector& x);
move (2)	vector& operator= (vector&& x);
initializer list (3)	vector& operator= (initializer_list<value_type> il);

// vector assignment
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> foo (3,0);
  std::vector<int> bar (5,0);

  bar = foo;
  foo = std::vector<int>();

  std::cout << "Size of foo: " << int(foo.size()) << '\n';
  std::cout << "Size of bar: " << int(bar.size()) << '\n';
  return 0;
}
  • assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
  • assign(n, elem); //将n个elem拷贝赋值给本身。
    1. 示例:
// vector assign
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> first;
  std::vector<int> second;
  std::vector<int> third;

  first.assign (7,100);             // 7 ints with a value of 100

  std::vector<int>::iterator it;
  it=first.begin()+1;

  second.assign (it,first.end()-1); // the 5 central values of first

  int myints[] = {1776,7,4};
  third.assign (myints,myints+3);   // assigning from array.

  std::cout << "Size of first: " << int (first.size()) << '\n';
  std::cout << "Size of second: " << int (second.size()) << '\n';
  std::cout << "Size of third: " << int (third.size()) << '\n';
  return 0;
}

Output:
Size of first: 7
Size of second: 5
Size of third: 3
  • push_back(ele); //尾部插入元素ele
  • pop_back(); //删除最后一个元素
  • insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
  • insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele
    1. 示例:
// inserting into a vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (3,100);
  std::vector<int>::iterator it;

  it = myvector.begin();
  it = myvector.insert ( it , 200 );

  myvector.insert (it,2,300);

  // "it" no longer valid, get a new one:
  it = myvector.begin();

  std::vector<int> anothervector (2,400);
  myvector.insert (it+2,anothervector.begin(),anothervector.end());

  int myarray [] = { 501,502,503 };
  myvector.insert (myvector.begin(), myarray, myarray+3);

  std::cout << "myvector contains:";
  for (it=myvector.begin(); it<myvector.end(); it++)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}


Output:
myvector contains: 501 502 503 300 300 400 400 200 100 100 100
  • erase(const_iterator pos); //删除迭代器指向的元素
  • erase(const_iterator start, const_iterator end); //删除迭代器从start到end之间的元素
    1. 示例:
// erasing from vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some values (from 1 to 10)
  for (int i=1; i<=10; i++) myvector.push_back(i);

  // erase the 6th element
  myvector.erase (myvector.begin()+5);

  // erase the first 3 elements:
  myvector.erase (myvector.begin(),myvector.begin()+3);

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); ++i)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

Output: myvector contains: 4 5 7 8 9 10
  • clear(); //删除容器中所有元素
  • swap(vec); // 将vec与本身的元素互换,实现两个容器内元素进行互换(两个容器对象都必须是相同的类型)
    1. swap可用于收缩内存: vector(v).swap(v); //匿名对象
    2. 例子:
// swap vectors
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> foo (3,100);   // three ints with a value of 100
  std::vector<int> bar (5,200);   // five ints with a value of 200

  foo.swap(bar);

  std::cout << "foo contains:";
  for (unsigned i=0; i<foo.size(); i++)
    std::cout << ' ' << foo[i];
  std::cout << '\n';

  std::cout << "bar contains:";
  for (unsigned i=0; i<bar.size(); i++)
    std::cout << ' ' << bar[i];
  std::cout << '\n';

  return 0;
}

Output:
foo contains: 200 200 200 200 200 
bar contains: 100 100 100
  • emplace: 通过在 position(参数)位置处插入新元素 args(参数)来扩展容器
    1. 参数: Position in the container where the new element is inserted.
    2. 返回值: An iterator that points to the newly emplaced element.
      案例:
// vector::emplace
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector = {10,20,30};

  auto it = myvector.emplace ( myvector.begin()+1, 100 );
  myvector.emplace ( it, 200 );
  myvector.emplace ( myvector.end(), 300 );

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

Output
myvector contains: 10 200 100 20 30 300
  • emplace_bace: 尾部插入新的元素
// vector::emplace_back
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector = {10,20,30};

  myvector.emplace_back (100);
  myvector.emplace_back (200);

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 10 20 30 100 200

array

  • 是固定大小的顺序容器

与vector不同的操作

  1. fill (更改元素操作)
  • 示例:
// array::fill example
#include <iostream>
#include <array>

int main () {
  std::array<int,6> myarray;

  myarray.fill(5);

  std::cout << "myarray contains:";
  for ( int& x : myarray) { std::cout << ' ' << x; }

  std::cout << '\n';

  return 0;
}

//Output:
//myarray contains: 5 5 5 5 5 5

deque

  • 参考链接: https://cplusplus.com/reference/deque/deque/


deque与vector区别:

  • vector对于头部的插入删除效率低,数据量越大,效率越低
  • deque相对而言,对头部的插入删除速度回比vector快
  • vector访问元素时的速度会比deque快,这和两者内部实现有关

Requirements

Header: <deque>
Namespace std

deque构造函数

函数原型:

  • deque<T> deqT; //默认构造形式
  • deque(beg, end); //构造函数将[beg, end)区间中的元素拷贝给本身。
  • deque(n, elem); //构造函数将n个elem拷贝给本身。
  • deque(const deque &deq); //拷贝构造函数
  • 示例:
// constructing deques
#include <iostream>
#include <deque>

int main ()
{
  unsigned int i;

  // constructors used in the same order as described above:
  std::deque<int> first;                                // empty deque of ints
  std::deque<int> second (4,100);                       // four ints with value 100
  std::deque<int> third (second.begin(),second.end());  // iterating through second
  std::deque<int> fourth (third);                       // a copy of third

  // the iterator constructor can be used to copy arrays:
  int myints[] = {16,2,77,29};
  std::deque<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  std::cout << "The contents of fifth are:";
  for (std::deque<int>::iterator it = fifth.begin(); it!=fifth.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

//Output
//The contents of fifth are: 16 2 77 29

iterators

  • 同vector

deque容量和大小(同vector)

  • size: 返回容器中元素的个数
  • empyt: 判断容器是否为空 空返回true
  • capacity: 容器的容量
  • void resize (size_type n);: 重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
    void resize (size_type n, const value_type& val);: 重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
  • max_size: 容器能够装下的 maximum number of elements
  • reserve: 减少vector在动态扩展容量时的扩展次数. reserve(int len);,容器预留len个元素长度,预留位置不初始化,元素不可访问。

元素访问(同vector)

  • operator[]; //返回索引idx所指的数据
  • at(int idx); //返回索引idx所指的数据
  • front(); //返回容器中第一个数据元素
  • back(); //返回容器中最后一个数据元素

元素更改

  • vector& operator=(const vector &vec);(同vector)//重载等号操作符

  • assign(beg, end); //(同vector)将[beg, end)区间中的数据拷贝赋值给本身。

  • assign(n, elem); //将n个elem拷贝赋值给本身。

  • push_back(ele); //(同vector)尾部插入元素ele

  • pop_back(); //(同vector)删除最后一个元素

  • push_front // 在容器头部插入一个数据

    • pop_front // 删除容器第一个数据
  • insert(const_iterator pos, ele); //(同vector)迭代器指向位置pos插入元素ele

  • insert(const_iterator pos, int count,ele);//(同vector)迭代器指向位置pos插入count个元素ele

  • erase(const_iterator pos); //(同vector)删除迭代器指向的元素

  • erase(const_iterator start, const_iterator end); //(同vector)删除迭代器从start到end之间的元素

  • clear(); //(同vector)删除容器中所有元素

  • swap(vec); //(同vector) 将vec与本身的元素互换,实现两个容器内元素进行互换(两个容器对象都必须是相同的类型)

    1. swap可用于收缩内存: vector(v).swap(v); //匿名对象
    2. 例子:
// swap vectors
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> foo (3,100);   // three ints with a value of 100
  std::vector<int> bar (5,200);   // five ints with a value of 200

  foo.swap(bar);

  std::cout << "foo contains:";
  for (unsigned i=0; i<foo.size(); i++)
    std::cout << ' ' << foo[i];
  std::cout << '\n';

  std::cout << "bar contains:";
  for (unsigned i=0; i<bar.size(); i++)
    std::cout << ' ' << bar[i];
  std::cout << '\n';

  return 0;
}

Output:
foo contains: 200 200 200 200 200 
bar contains: 100 100 100
  • emplace: 通过在 position(参数)位置处插入新元素 args(参数)来扩展容器
    1. 参数: Position in the container where the new element is inserted.
    2. 返回值: An iterator that points to the newly emplaced element.
      案例:
// vector::emplace
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector = {10,20,30};

  auto it = myvector.emplace ( myvector.begin()+1, 100 );
  myvector.emplace ( it, 200 );
  myvector.emplace ( myvector.end(), 300 );

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

Output
myvector contains: 10 200 100 20 30 300
  • emplace_bace: 尾部插入新的元素
// vector::emplace_back
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector = {10,20,30};

  myvector.emplace_back (100);
  myvector.emplace_back (200);

  std::cout << "myvector contains:";
  for (auto& x: myvector)
    std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

Output:
myvector contains: 10 20 30 100 200
  • emplace_front
  • emplace_back

queue

概念:Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口

  • https://cplusplus.com/reference/queue/

构造函数:

  • queue<T> que; //queue采用模板类实现,queue对象的默认构造形式
  • queue(const queue &que); //拷贝构造函数

数据存取(与deque不同之处)

  • push(elem); //往队尾添加元素
  • pop(); //从队头移除第一个元素

Stack

  • 概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口
  • https://cplusplus.com/reference/stack/stack/

数据存取

  • push(elem); //向栈顶添加元素
  • pop(); //从栈顶移除第一个元素
  • top(); //返回栈顶元素

List

功能将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的

  • https://cplusplus.com/reference/list/list/

构造函数

  • list<T> lst; //list采用采用模板类实现,对象的默认构造形式:
  • list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。
  • list(n,elem); //构造函数将n个elem拷贝给本身。
  • list(const list &lst); //拷贝构造函数。
  • 示例:
// constructing lists
#include <iostream>
#include <list>

int main ()
{
  // constructors used in the same order as described above:
  std::list<int> first;                                // empty list of ints
  std::list<int> second (4,100);                       // four ints with value 100
  std::list<int> third (second.begin(),second.end());  // iterating through second
  std::list<int> fourth (third);                       // a copy of third

  // the iterator constructor can also be used to construct from arrays:
  int myints[] = {16,2,77,29};
  std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  std::cout << "The contents of fifth are: ";
  for (std::list<int>::iterator it = fifth.begin(); it != fifth.end(); it++)
    std::cout << *it << ' ';

  std::cout << '\n';

  return 0;
}

//Output:
//The contents of fifth are: 16 2 77 29

Iterators(同vector)

capacity(同vector)

获取元素

  1. front
  2. back

更改元素(同deque)

Operations

  1. splice 转移元素从一个List到例外一个list上
  • 示例
// splicing lists
#include <iostream>
#include <list>

int main ()
{
  std::list<int> mylist1, mylist2;
  std::list<int>::iterator it;

  // set some initial values:
  for (int i=1; i<=4; ++i)
     mylist1.push_back(i);      // mylist1: 1 2 3 4

  for (int i=1; i<=3; ++i)
     mylist2.push_back(i*10);   // mylist2: 10 20 30

  it = mylist1.begin();
  ++it;                         // points to 2

  mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" still points to 2 (the 5th element)
                                          
  mylist2.splice (mylist2.begin(),mylist1, it);
                                // mylist1: 1 10 20 30 3 4
                                // mylist2: 2
                                // "it" is now invalid.
  it = mylist1.begin();
  std::advance(it,3);           // "it" points now to 30

  mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
                                // mylist1: 30 3 4 1 10 20

  std::cout << "mylist1 contains:";
  for (it=mylist1.begin(); it!=mylist1.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "mylist2 contains:";
  for (it=mylist2.begin(); it!=mylist2.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//mylist1 contains: 30 3 4 1 10 20
//mylist2 contains: 2
  1. sort(); //链表排序(用这个比用算法里的快)
  • 示例
// list::sort
#include <iostream>
#include <list>
#include <string>
#include <cctype>

// comparison, not case sensitive.
bool compare_nocase (const std::string& first, const std::string& second)
{
  unsigned int i=0;
  while ( (i<first.length()) && (i<second.length()) )
  {
    if (tolower(first[i])<tolower(second[i])) return true;
    else if (tolower(first[i])>tolower(second[i])) return false;
    ++i;
  }
  return ( first.length() < second.length() );
}

int main ()
{
  std::list<std::string> mylist;
  std::list<std::string>::iterator it;
  mylist.push_back ("one");
  mylist.push_back ("two");
  mylist.push_back ("Three");

  mylist.sort();

  std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  mylist.sort(compare_nocase);

  std::cout << "mylist contains:";
  for (it=mylist.begin(); it!=mylist.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//mylist contains: Three one two
//mylist contains: one Three tw
  1. reverse

set/multiset

  • https://cplusplus.com/reference/set/
  • 所有元素都会在插入时自动被排序
  • set/multiset属于关联式容器,底层结构是用二叉树实现。(or hashmap)
    set和multiset区别
  • set不允许容器中有重复的元素
  • multiset允许容器中有重复的元素

构造函数

  • set<T> st; //默认构造函数:
  • set(const set &st); //拷贝构造函数

插入和删除

  1. insert
  2. erase
  3. swap
  4. clear
  5. emplace
  6. emplace_hint

查找和统计

  1. find // //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
  2. count // 统计key的元素个数

map

  • https://cplusplus.com/reference/map/

简介:

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序
    优点:
  • 可以根据key值快速找到value值

构造函数和赋值

  1. map<T1, T2> mp; //map默认构造函数:
  2. map(const map &mp); //拷贝构造函数
  • 示例:
// constructing maps
#include <iostream>
#include <map>

bool fncomp (char lhs, char rhs) {return lhs<rhs;}

struct classcomp {
  bool operator() (const char& lhs, const char& rhs) const
  {return lhs<rhs;}
};

int main ()
{
  std::map<char,int> first;

  first['a']=10;
  first['b']=30;
  first['c']=50;
  first['d']=70;

  std::map<char,int> second (first.begin(),first.end());

  std::map<char,int> third (second);

  std::map<char,int,classcomp> fourth;                 // class as Compare

  bool(*fn_pt)(char,char) = fncomp;
  std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare

  return 0;
}
  1. operator=
// assignment operator with maps
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> first;
  std::map<char,int> second;

  first['x']=8;
  first['y']=16;
  first['z']=32;

  second=first;                // second now contains 3 ints
  first=std::map<char,int>();  // and first is now empty

  std::cout << "Size of first: " << first.size() << '\n';
  std::cout << "Size of second: " << second.size() << '\n';
  return 0;
}

//Output:
//Size of first: 0
//Size of second: 3

Iterator(与上面同)

容量和大小(同)

获取元素

  1. operator[]
  2. at

更改元素

  1. insert
// map::insert (C++98)
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  // first insert function version (single parameter):
  mymap.insert ( std::pair<char,int>('a',100) );
  mymap.insert ( std::pair<char,int>('z',200) );

  std::pair<std::map<char,int>::iterator,bool> ret;
  ret = mymap.insert ( std::pair<char,int>('z',500) );
  if (ret.second==false) {
    std::cout << "element 'z' already existed";
    std::cout << " with a value of " << ret.first->second << '\n';
  }

  // second insert function version (with hint position):
  std::map<char,int>::iterator it = mymap.begin();
  mymap.insert (it, std::pair<char,int>('b',300));  // max efficiency inserting
  mymap.insert (it, std::pair<char,int>('c',400));  // no max efficiency inserting

  // third insert function version (range insertion):
  std::map<char,int> anothermap;
  anothermap.insert(mymap.begin(),mymap.find('c'));

  // showing contents:
  std::cout << "mymap contains:\n";
  for (it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  std::cout << "anothermap contains:\n";
  for (it=anothermap.begin(); it!=anothermap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

//Output:
//element 'z' already existed with a value of 200
//mymap contains:
//a => 100
//b => 300
//c => 400
//z => 200
//anothermap contains:
//a => 100
//b => 30
  1. erase
  2. swap
  3. clear
  4. emplace
  5. emplace_hint

algorithm

  • https://cplusplus.com/reference/algorithm/

Requirements

Header: <algorithm>
Namespace std

不更改序列的操作

简单查找算法,要求输入迭代器(input iterator)

  1. find(beg, end, val); // 返回一个迭代器,指向输入序列中第一个等于 val 的元素,未找到返回 end
  • 示例
// The function uses operator== to compare the individual elements to val

// find example
#include <iostream>     // std::cout
#include <algorithm>    // std::find
#include <vector>       // std::vector

int main () {
  // using std::find with array and pointer:
  int myints[] = { 10, 20, 30, 40 };
  int * p;

  p = std::find (myints, myints+4, 30);
  if (p != myints+4)
    std::cout << "Element found in myints: " << *p << '\n';
  else
    std::cout << "Element not found in myints\n";

  // using std::find with vector and iterator:
  std::vector<int> myvector (myints,myints+4);
  std::vector<int>::iterator it;

  it = find (myvector.begin(), myvector.end(), 30);
  if (it != myvector.end())
    std::cout << "Element found in myvector: " << *it << '\n';
  else
    std::cout << "Element not found in myvector\n";

  return 0;
}

// Output
// Element found in myints: 30
// Element found in myvector: 30
  1. find_if(beg, end, unaryPred); // 返回一个迭代器,指向第一个满足 unaryPred 的元素,未找到返回 end
  • 示例
// find_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector

bool IsOdd (int i) {
  return ((i%2)==1);
}

int main () {
  std::vector<int> myvector;

  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);

  std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
  std::cout << "The first odd value is " << *it << '\n';

  return 0;
}

// Output
// The first odd value is 25
  1. find_if_not(beg, end, unaryPred); // 返回一个迭代器,指向第一个令 unaryPred 为 false 的元素,未找到返回 end
  • 示例:
// find_if_not example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if_not
#include <array>        // std::array

int main () {
  std::array<int,5> foo = {1,2,3,4,5};

  std::array<int,5>::iterator it =
    std::find_if_not (foo.begin(), foo.end(), [](int i){return i%2;} );
  std::cout << "The first even value is " << *it << '\n';

  return 0;
}

// Output
// The first even value is 2
  1. count(beg, end, val); // 返回一个计数器,指出 val 出现了多少次
// count algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::count
#include <vector>       // std::vector

int main () {
  // counting elements in array:
  int myints[] = {10,20,30,30,20,10,10,20};   // 8 elements
  int mycount = std::count (myints, myints+8, 10);
  std::cout << "10 appears " << mycount << " times.\n";

  // counting elements in container:
  std::vector<int> myvector (myints, myints+8);
  mycount = std::count (myvector.begin(), myvector.end(), 20);
  std::cout << "20 appears " << mycount  << " times.\n";

  return 0;
}

// Output
// 10 appears 3 times.
// 20 appears 3 times.
  1. count_if(beg, end, unaryPred); // 统计有多少个元素满足 unaryPred
  2. all_of(beg, end, unaryPred); // 返回一个 bool 值,判断是否所有元素都满足 unaryPred
  • 示例:
// all_of example
#include <iostream>     // std::cout
#include <algorithm>    // std::all_of
#include <array>        // std::array

int main () {
  std::array<int,8> foo = {3,5,7,11,13,17,19,23};

  if ( std::all_of(foo.begin(), foo.end(), [](int i){return i%2;}) )
    std::cout << "All the elements are odd numbers.\n";

  return 0;
}

// Output
// All the elements are odd numbers.
  1. any_of(beg, end, unaryPred); // 返回一个 bool 值,判断是否任意(存在)一个元素满足 unaryPred
  • 示例
// any_of example
#include <iostream>     // std::cout
#include <algorithm>    // std::any_of
#include <array>        // std::array

int main () {
  std::array<int,7> foo = {0,1,-1,3,-3,5,-5};

  if ( std::any_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
    std::cout << "There are negative elements in the range.\n";

  return 0;
}

// Output
// There are negative elements in the range.
  1. none_of(beg, end, unaryPred); // 返回一个 bool 值,判断是否所有元素都不满足 unaryPred
  • 示例
// none_of example
#include <iostream>     // std::cout
#include <algorithm>    // std::none_of
#include <array>        // std::array

int main () {
  std::array<int,8> foo = {1,2,4,8,16,32,64,128};

  if ( std::none_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
    std::cout << "There are no negative elements in the range.\n";

  return 0;
}

// Output
// There are no negative elements in the range.

查找重复值的算法,传入向前迭代器(forward iterator)

  1. adjacent_find(beg, end); // 返回指向第一对相邻重复元素的迭代器,无相邻元素则返回 end
  • 示例
// adjacent_find example
#include <iostream>     // std::cout
#include <algorithm>    // std::adjacent_find
#include <vector>       // std::vector

bool myfunction (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {5,20,5,30,30,20,10,10,20};
  std::vector<int> myvector (myints,myints+8);
  std::vector<int>::iterator it;

  // using default comparison:
  it = std::adjacent_find (myvector.begin(), myvector.end());

  if (it!=myvector.end())
    std::cout << "the first pair of repeated elements are: " << *it << '\n';

  //using predicate comparison:
  it = std::adjacent_find (++it, myvector.end(), myfunction);

  if (it!=myvector.end())
    std::cout << "the second pair of repeated elements are: " << *it << '\n';

  return 0;
}

// Output
// the first pair of repeated elements are: 30
// the second pair of repeated elements are: 10
  1. search_n(beg, end, count, val); // 返回一个迭代器,从此位置开始有 count 个相等元素,不存在则返回 end
  • 示例:
// search_n example
#include <iostream>     // std::cout
#include <algorithm>    // std::search_n
#include <vector>       // std::vector

bool mypredicate (int i, int j) {
  return (i==j);
}

int main () {
  int myints[]={10,20,30,30,20,10,10,20};
  std::vector<int> myvector (myints,myints+8);

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

  // using default comparison:
  it = std::search_n (myvector.begin(), myvector.end(), 2, 30);

  if (it!=myvector.end())
    std::cout << "two 30s found at position " << (it-myvector.begin()) << '\n';
  else
    std::cout << "match not found\n";

  // using predicate comparison:
  it = std::search_n (myvector.begin(), myvector.end(), 2, 10, mypredicate);

  if (it!=myvector.end())
    std::cout << "two 10s found at position " << int(it-myvector.begin()) << '\n';
  else
    std::cout << "match not found\n";

  return 0;
}

// Output
// Two 30s found at position 2
// Two 10s found at position 5

查找子序列算法,除 find_first_of(前两个输入迭代器,后两个前向迭代器) 外,都要求两个前向迭代器

  1. search(beg1, end1, beg2, end2); // 返回第二个输入范围(子序列)在第一个输入范围中第一次出现的位置,未找到则返回 end1
  2. search(beg1, end1, beg2, end2, binaryPred); // 返回第二个输入范围(子序列)在爹一个输入范围中第一次出现的位置,未找到则返回 end1
  • 示例:
// search algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::search
#include <vector>       // std::vector

bool mypredicate (int i, int j) {
  return (i==j);
}

int main () {
  std::vector<int> haystack;

  // set some values:        haystack: 10 20 30 40 50 60 70 80 90
  for (int i=1; i<10; i++) haystack.push_back(i*10);

  // using default comparison:
  int needle1[] = {40,50,60,70};
  std::vector<int>::iterator it;
  it = std::search (haystack.begin(), haystack.end(), needle1, needle1+4);

  if (it!=haystack.end())
    std::cout << "needle1 found at position " << (it-haystack.begin()) << '\n';
  else
    std::cout << "needle1 not found\n";

  // using predicate comparison:
  int needle2[] = {20,30,50};
  it = std::search (haystack.begin(), haystack.end(), needle2, needle2+3, mypredicate);

  if (it!=haystack.end())
    std::cout << "needle2 found at position " << (it-haystack.begin()) << '\n';
  else
    std::cout << "needle2 not found\n";

  return 0;
}

// Output
// needle1 found at position 3
// needle2 not found
  1. find_end(beg1, end1, beg2, end2); // 类似 search,但返回的最后一次出现的位置。如果第二个输入范围为空,或者在第一个输入范围为空,或者在第一个输入范围中未找到它,则返回 end1
  2. find_end(beg1, end1, beg2, end2, binaryPred); // 类似 search,但返回的最后一次出现的位置。如果第二个输入范围为空,或者在第一个输入范围为空,或者在第一个输入范围中未找到它,则返回 end1
  • 示例:
// find_end example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_end
#include <vector>       // std::vector

bool myfunction (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {1,2,3,4,5,1,2,3,4,5};
  std::vector<int> haystack (myints,myints+10);

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

  // using default comparison:
  std::vector<int>::iterator it;
  it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3);

  if (it!=haystack.end())
    std::cout << "needle1 last found at position " << (it-haystack.begin()) << '\n';

  int needle2[] = {4,5,1};

  // using predicate comparison:
  it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction);

  if (it!=haystack.end())
    std::cout << "needle2 last found at position " << (it-haystack.begin()) << '\n';

  return 0;
}

// Output
// needle1 last found at position 5
// needle2 last found at position 3
  1. find_first_of(beg1, end1, beg2, end2); // 返回一个迭代器,指向第二个输入范围中任意元素在第一个范围中首次出现的位置,未找到则返回end1
  2. find_first_of(beg1, end1, beg2, end2, binaryPred); // 返回一个迭代器,指向第二个输入范围中任意元素在第一个范围中首次出现的位置,未找到则返回end1
  • 示例
// find_first_of example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_first_of
#include <vector>       // std::vector
#include <cctype>       // std::tolower

bool comp_case_insensitive (char c1, char c2) {
  return (std::tolower(c1)==std::tolower(c2));
}

int main () {
  int mychars[] = {'a','b','c','A','B','C'};
  std::vector<char> haystack (mychars,mychars+6);
  std::vector<char>::iterator it;

  int needle[] = {'A','B','C'};

  // using default comparison:
  it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3);

  if (it!=haystack.end())
    std::cout << "The first match is: " << *it << '\n';

  // using predicate comparison:
  it = find_first_of (haystack.begin(), haystack.end(),
                      needle, needle+3, comp_case_insensitive);

  if (it!=haystack.end())
    std::cout << "The first match is: " << *it << '\n';

  return 0;
}

// Output
// The first match is: A
// The first match is: a

其他只读算法,传入输入迭代器

  1. for_each(beg, end, unaryOp); // 对输入序列中的每个元素应用可调用对象 unaryOp,unaryOp 的返回值被忽略
  • 示例:
// for_each example
#include <iostream>     // std::cout
#include <algorithm>    // std::for_each
#include <vector>       // std::vector

void myfunction (int i) {  // function:
  std::cout << ' ' << i;
}

struct myclass {           // function object type:
  void operator() (int i) {std::cout << ' ' << i;}
} myobject;

int main () {
  std::vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  std::cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myfunction);
  std::cout << '\n';

  // or:
  std::cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myobject);
  std::cout << '\n';

  return 0;
}

// Output
// myvector contains: 10 20 30
// myvector contains: 10 20 30
  1. equal(beg1, end1, beg2); // 比较每个元素,确定两个序列是否相等。
  2. equal(beg1, end1, beg2, binaryPred); // 比较每个元素,确定两个序列是否相等。
  • 示例
// equal algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::equal
#include <vector>       // std::vector

bool mypredicate (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {20,40,60,80,100};               //   myints: 20 40 60 80 100
  std::vector<int>myvector (myints,myints+5);     // myvector: 20 40 60 80 100

  // using default comparison:
  if ( std::equal (myvector.begin(), myvector.end(), myints) )
    std::cout << "The contents of both sequences are equal.\n";
  else
    std::cout << "The contents of both sequences differ.\n";

  myvector[3]=81;                                 // myvector: 20 40 60 81 100

  // using predicate comparison:
  if ( std::equal (myvector.begin(), myvector.end(), myints, mypredicate) )
    std::cout << "The contents of both sequences are equal.\n";
  else
    std::cout << "The contents of both sequences differ.\n";

  return 0;
}

// Output
// The contents of both sequences are equal.
// The contents of both sequence differ.
​```c++
// mismatch algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::mismatch
#include <vector>       // std::vector
#include <utility>      // std::pair

bool mypredicate (int i, int j) {
  return (i==j);
}

int main () {
  std::vector<int> myvector;
  for (int i=1; i<6; i++) myvector.push_back (i*10); // myvector: 10 20 30 40 50

  int myints[] = {10,20,80,320,1024};                //   myints: 10 20 80 320 1024

  std::pair<std::vector<int>::iterator,int*> mypair;

  // using default comparison:
  mypair = std::mismatch (myvector.begin(), myvector.end(), myints);
  std::cout << "First mismatching elements: " << *mypair.first;
  std::cout << " and " << *mypair.second << '\n';

  ++mypair.first; ++mypair.second;

  // using predicate comparison:
  mypair = std::mismatch (mypair.first, myvector.end(), mypair.second, mypredicate);
  std::cout << "Second mismatching elements: " << *mypair.first;
  std::cout << " and " << *mypair.second << '\n';

  return 0;
}

// Output
// First mismatching elements: 30 and 80
// Second mismatching elements: 40 and 320

更改序列的操作

使用输入迭代器的写算法,读取一个输入序列,将值写入到一个输出序列(dest)中

  1. copy(beg, end, dest); // 从输入范围将元素拷贝所有元素到 dest 指定定的目的序列
  • 示例:
// copy algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector (7);

  std::copy ( myints, myints+7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

// Output
// myvector contains: 10 20 30 40 50 60 70
  1. copy_if(beg, end, dest, unaryPred); // 从输入范围将元素拷贝满足 unaryPred 的元素到 dest 指定定的目的序列
  • 示例
// copy_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy_if, std::distance
#include <vector>       // std::vector

int main () {
  std::vector<int> foo = {25,15,5,-5,-15};
  std::vector<int> bar (foo.size());

  // copy only positive numbers:
  auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );
  bar.resize(std::distance(bar.begin(),it));  // shrink container to new size

  std::cout << "bar contains:";
  for (int& x: bar) std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

// Output
// bar contains: 25 15 5
  1. copy_n(beg, n, dest); // 从输入范围将元素拷贝前 n 个元素到 dest 指定定的目的序列
  • 示例
// copy_n algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector;

  myvector.resize(7);   // allocate space for 7 elements

  std::copy_n ( myints, 7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

// Output
// myvector contains: 10 20 30 40 50 60 70
  1. move(beg, end, dest); // 对输入序列中的每个元素调用 std::move,将其移动到迭代器 dest 开始始的序列中
  • 示例:
// move algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::move (ranges)
#include <utility>      // std::move (objects)
#include <vector>       // std::vector
#include <string>       // std::string

int main () {
  std::vector<std::string> foo = {"air","water","fire","earth"};
  std::vector<std::string> bar (4);

  // moving ranges:
  std::cout << "Moving ranges...\n";
  std::move ( foo.begin(), foo.begin()+4, bar.begin() );

  std::cout << "foo contains " << foo.size() << " elements:";
  std::cout << " (each in an unspecified but valid state)";
  std::cout << '\n';

  std::cout << "bar contains " << bar.size() << " elements:";
  for (std::string& x: bar) std::cout << " [" << x << "]";
  std::cout << '\n';

  // moving container:
  std::cout << "Moving container...\n";
  foo = std::move (bar);

  std::cout << "foo contains " << foo.size() << " elements:";
  for (std::string& x: foo) std::cout << " [" << x << "]";
  std::cout << '\n';

  std::cout << "bar is in an unspecified but valid state";
  std::cout << '\n';

  return 0;
}

// Output
// Moving ranges...
// foo contains 4 elements: (each in an unspecified but valid state)
// bar contains 4 elements: [air] [water] [fire] [earth]
// Moving container...
// foo contains 4 elements: [air] [water] [fire] [earth]
// bar is in an unspecified but valid state
  1. transform(beg, end, dest, unaryOp); // 调用给定操作(一元操作),并将结果写到dest中
  2. transform(beg, end, beg2, dest, binaryOp); // 调用给定操作(二元操作),并将结果写到dest中
  • 示例
// transform algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::transform
#include <vector>       // std::vector
#include <functional>   // std::plus

int op_increase (int i) { return ++i; }

int main () {
  std::vector<int> foo;
  std::vector<int> bar;

  // set some values:
  for (int i=1; i<6; i++)
    foo.push_back (i*10);                         // foo: 10 20 30 40 50

  bar.resize(foo.size());                         // allocate space

  std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
                                                  // bar: 11 21 31 41 51

  // std::plus adds together its two arguments:
  std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
                                                  // foo: 21 41 61 81 101

  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output
// foo contains: 21 41 61 81 101
  1. replace_copy(beg, end, dest, old_val, new_val); // 将每个元素拷贝到 dest,将等于 old_val 的的元素替换为 new_val
  • 示例
// replace_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_copy
#include <vector>       // std::vector

int main () {
  int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };

  std::vector<int> myvector (8);
  std::replace_copy (myints, myints+8, myvector.begin(), 20, 99);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output
// myvector contains: 10 99 30 30 99 10 10 99
  1. replace_copy_if(beg, end, dest, unaryPred, new_val); // 将每个元素拷贝到 dest,将满足 unaryPred 的的元素替换为 new_val
  • 示例
// replace_copy_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_copy_if
#include <vector>       // std::vector

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
  std::vector<int> foo,bar;

  // set some values:
  for (int i=1; i<10; i++) foo.push_back(i);          // 1 2 3 4 5 6 7 8 9

  bar.resize(foo.size());   // allocate space
  std::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);  // 0 2 0 4 0 6 0 8 0

  std::cout << "bar contains:";
  for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output:
// second contains: 0 2 0 4 0 6 0 8 0

使用前向迭代器的写算法,要求前向迭代器

  1. iter_swap(iter1, iter2); // 交换 iter1 和 iter2 所表示的元素,返回 void
  • 示例
// iter_swap example
#include <iostream>     // std::cout
#include <algorithm>    // std::iter_swap
#include <vector>       // std::vector

int main () {

  int myints[]={10,20,30,40,50 };              //   myints:  10  20  30  40  50
  std::vector<int> myvector (4,99);            // myvector:  99  99  99  99

  std::iter_swap(myints,myvector.begin());     //   myints: [99] 20  30  40  50
                                               // myvector: [10] 99  99  99

  std::iter_swap(myints+3,myvector.begin()+2); //   myints:  99  20  30 [99] 50
                                               // myvector:  10  99 [40] 99

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output:
// myvector contains: 10 99 40 99
  1. swap_ranges(beg1, end1, beg2); // 将输入范围中所有元素与 beg2 开始的第二个序列中所有元素进行交换。返回递增后的的 beg2,指向最后一个交换元素之后的位置。
  • 示例:
// swap_ranges example
#include <iostream>     // std::cout
#include <algorithm>    // std::swap_ranges
#include <vector>       // std::vector

int main () {
  std::vector<int> foo (5,10);        // foo: 10 10 10 10 10
  std::vector<int> bar (5,33);        // bar: 33 33 33 33 33

  std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());

  // print out results of swap:
  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "bar contains:";
  for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output:
// foo contains: 10 33 33 33 10
// bar contains: 10 10 10 33 33
  1. replace(beg, end, old_val, new_val); // 用 new_val 替换等于 old_val 的每个匹配元素
  2. replace_if(beg, end, unaryPred, new_val); // 用 new_val 替换满足 unaryPred 的每个匹配元素
  • 示例
// replace_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_if
#include <vector>       // std::vector

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; i++) myvector.push_back(i);               // 1 2 3 4 5 6 7 8 9

  std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output:
// myvector contains: 0 2 0 4 0 6 0 8 0

使用双向迭代器的写算法,要求双向选代器(bidirectional iterator)

  1. copy_backward(beg, end, dest); // 从输入范围中拷贝元素到指定目的位置。如果范围为空,则返回值为 dest;否则,返回值表示从 *beg 中拷贝或移动的元素。
  • 示例:
// copy_backward example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy_backward
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<=5; i++)
    myvector.push_back(i*10);          // myvector: 10 20 30 40 50

  myvector.resize(myvector.size()+3);  // allocate space for 3 more elements

  std::copy_backward ( myvector.begin(), myvector.begin()+5, myvector.end() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output:
// myvector contains: 10 20 30 10 20 30 40 50
  1. move_backward(beg, end, dest); // 从输入范围中移动元素到指定目的位置。如果范围为空,则返回值为 dest;否则,返回值表示从 *beg 中拷贝或移动的元素。
// move_backward example
#include <iostream>     // std::cout
#include <algorithm>    // std::move_backward
#include <string>       // std::string

int main () {
  std::string elems[10] = {"air","water","fire","earth"};

  // insert new element at the beginning:
  std::move_backward (elems,elems+4,elems+5);
  elems[0]="ether";

  std::cout << "elems contains:";
  for (int i=0; i<10; ++i)
    std::cout << " [" << elems[i] << "]";
  std::cout << '\n';

  return 0;
}

//Output:
//elems contains: [ether] [air] [water] [fire] [earth] [] [] [] [] []

只写不读算法,要求输出迭代器(output iterator)

  1. fill(beg, end, val); // 将 val 赋予每个元素,返回 void
  2. fill_n(beg, cnt, val); // 将 val 赋予 cnt 个元素,返回指向写入到输出序列最有一个元素之后位置的迭代器
  • 示例:
// fill algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::fill
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector (8);                       // myvector: 0 0 0 0 0 0 0 0

  std::fill (myvector.begin(),myvector.begin()+4,5);   // myvector: 5 5 5 5 0 0 0 0
  std::fill (myvector.begin()+3,myvector.end()-2,8);   // myvector: 5 5 5 8 8 8 0 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 5 5 5 8 8 8 0 0
  1. genetate(beg, end, Gen); // 每次调用 Gen() 生成不同的值赋予每个序列,返回 void
  2. genetate_n(beg, cnt, Gen); // 每次调用 Gen() 生成不同的值赋予 cnt 个序列,返回指向写入到输出序列最有一个元素之后位置的迭代器

使用随机访问迭代器的重排算法

  1. random_shuffle(beg, end); // 混洗输入序列中的元素,返回 void
  2. random_shuffle(beg, end, rand); // 混洗输入序列中的元素,rand 接受一个正整数的随机对象,返回 void
  • 示例
// random_shuffle example
#include <iostream>     // std::cout
#include <algorithm>    // std::random_shuffle
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// random generator function:
int myrandom (int i) { return std::rand()%i;}

int main () {
  std::srand ( unsigned ( std::time(0) ) );
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  // using built-in random generator:
  std::random_shuffle ( myvector.begin(), myvector.end() );

  // using myrandom:
  std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

// Possible output:
// myvector contains: 3 4 1 6 8 9 2 7 5
  1. shuffle(beg, end, Uniform_rand); // 混洗输入序列中的元素,Uniform_rand 必须满足均匀分布随机数生成器的要求,返回 void
  • 示例
// shuffle algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::shuffle
#include <array>        // std::array
#include <random>       // std::default_random_engine
#include <chrono>       // std::chrono::system_clock

int main () {
  std::array<int,5> foo {1,2,3,4,5};

  // obtain a time-based seed:
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

  shuffle (foo.begin(), foo.end(), std::default_random_engine(seed));

  std::cout << "shuffled elements:";
  for (int& x: foo) std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}

//Possible output:
//shuffled elements: 3 1 4 2 5

使用双向迭代器的重排算法

  1. reverse(beg, end); // 翻转序列中的元素,返回 void
  • 示例
// reverse algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::reverse
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9

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

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 9 8 7 6 5 4 3 2 1
  1. reverse_copy(beg, end, dest); // 翻转序列中的元素,返回一个迭代器,指向拷贝到目的序列的元素的尾后位置
  • 示例
// reverse_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::reverse_copy
#include <vector>       // std::vector

int main () {
  int myints[] ={1,2,3,4,5,6,7,8,9};
  std::vector<int> myvector;

  myvector.resize(9);    // allocate space

  std::reverse_copy (myints, myints+9, myvector.begin());

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 9 8 7 6 5 4 3 2 1

使用前向迭代器的重排算法

  • 普通版本在输入序列自身内部重拍元素,_copy 版本完成重拍后写入到指定目的序列中,而不改变输入序列
  1. remove(beg, end, val); // 通过用保留的元素覆盖要删除的元素实现删除 ==val 的元素,返回一个指向最后一个删除元素的尾后位置的迭代器
  • 示例:
// remove algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};      // 10 20 30 30 20 10 10 20

  // bounds of range:
  int* pbegin = myints;                          // ^
  int* pend = myints+sizeof(myints)/sizeof(int); // ^                       ^

  pend = std::remove (pbegin, pend, 20);         // 10 30 30 10 10 ?  ?  ?
                                                 // ^              ^
  std::cout << "range contains:";
  for (int* p=pbegin; p!=pend; ++p)
    std::cout << ' ' << *p;
  std::cout << '\n';

  return 0;
}

// Output
// range contains: 10 30 30 10 10
  1. remove_if(beg, end, unaryPred); // 通过用保留的元素覆盖要删除的元素实现删除满足 unaryPred 的元素,返回一个指向最后一个删除元素的尾后位置的迭代器
  • 示例
// remove_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_if

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
  int myints[] = {1,2,3,4,5,6,7,8,9};            // 1 2 3 4 5 6 7 8 9

  // bounds of range:
  int* pbegin = myints;                          // ^
  int* pend = myints+sizeof(myints)/sizeof(int); // ^                 ^

  pend = std::remove_if (pbegin, pend, IsOdd);   // 2 4 6 8 ? ? ? ? ?
                                                 // ^       ^
  std::cout << "the range contains:";
  for (int* p=pbegin; p!=pend; ++p)
    std::cout << ' ' << *p;
  std::cout << '\n';

  return 0;
}

//Output:
//the range contains: 2 4 6 8
  1. remove_copy(beg, end, dest, val); // 通过用保留的元素覆盖要删除的元素实现删除 ==val 的元素,返回一个指向最后一个删除元素的尾后位置的迭代器
  2. remove_copy_if(beg, end, dest, unaryPred); // 通过用保留的元素覆盖要删除的元素实现删除满足 unaryPred 的元素,返回一个指向最后一个删除元素的尾后位置的迭代器
  • 示例:
// remove_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_copy
#include <vector>       // std::vector

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};               // 10 20 30 30 20 10 10 20
  std::vector<int> myvector (8);

  std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 30 30 10 10 0 0 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 10 30 30 10 10 0 0 0
  1. unique(beg, end); // 通过对覆盖相邻的重复元素(用 == 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置
  2. unique (beg, end, binaryPred); // 通过对覆盖相邻的重复元素(用 binaryPred 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置
  • 示例:
// unique algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::unique, std::distance
#include <vector>       // std::vector

bool myfunction (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {10,20,20,20,30,30,20,20,10};           // 10 20 20 20 30 30 20 20 10
  std::vector<int> myvector (myints,myints+9);

  // using default comparison:
  std::vector<int>::iterator it;
  it = std::unique (myvector.begin(), myvector.end());   // 10 20 30 20 10 ?  ?  ?  ?
                                                         //                ^

  myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10

  // using predicate comparison:
  std::unique (myvector.begin(), myvector.end(), myfunction);   // (no changes)

  // print out content:
  std::cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 10 20 30 20 10
  1. unique_copy(beg, end, dest); // 通过对覆盖相邻的重复元素(用 == 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置
  2. unique_copy_if(beg, end, dest, binaryPred); // 通过对覆盖相邻的重复元素(用 binaryPred 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置
  • 示例:
// unique algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::unique, std::distance
#include <vector>       // std::vector

bool myfunction (int i, int j) {
  return (i==j);
}

int main () {
  int myints[] = {10,20,20,20,30,30,20,20,10};           // 10 20 20 20 30 30 20 20 10
  std::vector<int> myvector (myints,myints+9);

  // using default comparison:
  std::vector<int>::iterator it;
  it = std::unique (myvector.begin(), myvector.end());   // 10 20 30 20 10 ?  ?  ?  ?
                                                         //                ^

  myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10

  // using predicate comparison:
  std::unique (myvector.begin(), myvector.end(), myfunction);   // (no changes)

  // print out content:
  std::cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 10 20 30 20 10
  1. rotate(beg, mid, end); // 围绕 mid 指向的元素进行元素转动。元素 mid 成为为首元素,随后是 mid+1 到到 end 之前的元素,再接着是 beg 到 mid 之前的元素。返回一个迭代器,指向原来在 beg 位置的元素
  2. rotate_copy(beg, mid, end, dest); // 围绕 mid 指向的元素进行元素转动。元素 mid 成为为首元素,随后是 mid+1 到到 end 之前的元素,再接着是 beg 到 mid 之前的元素。返回一个迭代器,指向原来在 beg 位置的元素
  • 示例
// rotate algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::rotate
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  std::rotate(myvector.begin(),myvector.begin()+3,myvector.end());
                                                  // 4 5 6 7 8 9 1 2 3
  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 4 5 6 7 8 9 1 2 3

Partitions算法

  1. partition(beg, end, unaryPred); // 使用 unaryPred 划分输入序列。满足 unaryPred 的元素放置在序列开始,不满足的元素放在序列尾部。返回一个迭代器,指向最后一个满足 unaryPred 的元素之后的位置如果所有元素都不满足 unaryPred,则返回 beg
  • 示例
// partition algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::partition
#include <vector>       // std::vector

bool IsOdd (int i) { return (i%2)==1; }

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  std::vector<int>::iterator bound;
  bound = std::partition (myvector.begin(), myvector.end(), IsOdd);

  // print out content:
  std::cout << "odd elements:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "even elements:";
  for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Possible output:
// odd elements: 1 9 3 7 5
// even elements: 6 4 8 2
  1. is_partitioned(beg, end, unaryPred); // 如果所有满足谓词 unaryPred 的元素都在不满足 unarypred 的元素之前,则返回 true。若序列为空,也返回 true
  • 示例
// is_partitioned example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_partitioned
#include <array>        // std::array

bool IsOdd (int i) { return (i%2)==1; }

int main () {
  std::array<int,7> foo {1,2,3,4,5,6,7};

  // print contents:
  std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
  if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
    std::cout << " (partitioned)\n";
  else
    std::cout << " (not partitioned)\n";

  // partition array:
  std::partition (foo.begin(),foo.end(),IsOdd);

  // print contents again:
  std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
  if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
    std::cout << " (partitioned)\n";
  else
    std::cout << " (not partitioned)\n";

  return 0;
}

// Possible output:
// foo: 1 2 3 4 5 6 7 (not partitioned)
// foo: 1 7 3 5 4 6 2 (partitioned)
  1. partition_copy(beg, end, dest1, dest2, unaryPred); // 将满足 unaryPred 的元素拷贝到到 dest1,并将不满足 unaryPred 的元素拷贝到到 dest2。返回一个迭代器 pair,其 first 成员表示拷贝到 dest1 的的元素的末尾,second 表示拷贝到 dest2 的元素的末尾。
  2. partitioned_point(beg, end, unaryPred); // 输入序列必须是已经用 unaryPred 划分过的。返回满足 unaryPred 的范围的尾后迭代器。如果返回的迭代器不是 end,则它指向的元素及其后的元素必须都不满足 unaryPred
  3. stable_partition(beg, end, unaryPred); // 使用 unaryPred 划分输入序列。满足 unaryPred 的元素放置在序列开始,不满足的元素放在序列尾部。返回一个迭代器,指向最后一个满足 unaryPred 的元素之后的位置如果所有元素都不满足 unaryPred,则返回 beg

Binary search(在分区/排序范围内操作)

  • 二分搜索算法,传入前向迭代器或随机访问迭代器(random-access iterator),要求序列中的元素已经是有序的。通过小于运算符(<)或 comp 比较操作实现比较。
  1. binary_search(beg, end, val); // 返回一个 bool 值,指出序列中是否包含等于 val 的元素。对于两个值 x 和 y,当 x 不小于 y 且 y 也不小于 x 时,认为它们相等。
  • 示例:
// binary_search example
#include <iostream>     // std::cout
#include <algorithm>    // std::binary_search, std::sort
#include <vector>       // std::vector

bool myfunction (int i,int j) { return (i<j); }

int main () {
  int myints[] = {1,2,3,4,5,4,3,2,1};
  std::vector<int> v(myints,myints+9);                         // 1 2 3 4 5 4 3 2 1

  // using default comparison:
  std::sort (v.begin(), v.end());

  std::cout << "looking for a 3... ";
  if (std::binary_search (v.begin(), v.end(), 3))
    std::cout << "found!\n"; else std::cout << "not found.\n";

  // using myfunction as comp:
  std::sort (v.begin(), v.end(), myfunction);

  std::cout << "looking for a 6... ";
  if (std::binary_search (v.begin(), v.end(), 6, myfunction))
    std::cout << "found!\n"; else std::cout << "not found.\n";

  return 0;
}

//Output:
//looking for a 3... found!
//looking for a 6... not found.
  1. lower_bound(beg, end, val); // 返回一个非递减序列 [beg, end) 中的第一个大于等于值 val 的位置的迭代器,不存在则返回 end
  2. lower_bound(beg, end, val, comp); // 返回一个非递减序列 [beg, end) 中的第一个大于等于值 val 的位置的迭代器,不存在则返回 end
  3. upper_bound(beg, end, val); // 返回一个非递减序列 [beg, end) 中第一个大于 val 的位置的迭代器,不存在则返回 end
    upper_bound(beg, end, val, comp); // 返回一个非递减序列 [beg, end) 中第一个大于 val 的位置的迭代器,不存在则返回 end
  4. equal_range(beg, end, val); // 返回一个 pair,其 first 成员是 lower_bound 返回的迭代器,其 second 成员是 upper_bound 返回的迭代器

Merge(operating on sorted ranges)

  1. merge(beg1, end1, beg2, end2, dest); // 两个输入序列必须都是有序的,用 < 运算符将合并后的序列写入到 dest 中
  2. merge(beg1, end1, beg2, end2, dest, comp); // 两个输入序列必须都是有序的,使用给定的比较操作(comp)将合并后的序列写入到 dest 中
  • 示例:
// merge algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::merge, std::sort
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);

  std::sort (first,first+5);
  std::sort (second,second+5);
  std::merge (first,first+5,second,second+5,v.begin());

  std::cout << "The resulting vector contains:";
  for (std::vector<int>::iterator it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

// Output
// The resulting vector contains: 5 10 10 15 20 20 25 30 40 50
  1. inplace_merge(beg, mid, end); // 将同一个序列中的两个有序子序列合并为单一的有序序列。beg 到 mid 间的子序列和 mid 到 end 间的子序列被合并,并被写入到原序列中。使用 < 比较元素。
  2. inplace_merge(beg, mid, end, comp); // 将同一个序列中的两个有序子序列合并为单一的有序序列。beg 到 mid 间的子序列和 mid 到 end 间的子序列被合并,并被写入到原序列中。使用给定的 comp 操作。

Sorting(排序算法)

  • 要求随机访问迭代器(random-access iterator)
  1. sort(beg, end); // 排序整个范围
  2. sort(beg, end, comp); // 排序整个范围
  • 示例
// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

  // using default comparison (operator <):
  std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // using function as comp
  std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

  // using object as comp
  std::sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Output:
//myvector contains: 12 26 32 33 45 53 71 80
  1. stable_sort(beg, end); // 排序整个范围(稳定排序)
  2. stable_sort(beg, end, comp); // 排序整个范围(稳定排序)
  • 示例
// stable_sort example
#include <iostream>     // std::cout
#include <algorithm>    // std::stable_sort
#include <vector>       // std::vector

bool compare_as_ints (double i,double j)
{
  return (int(i)<int(j));
}

int main () {
  double mydoubles[] = {3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58};

  std::vector<double> myvector;

  myvector.assign(mydoubles,mydoubles+8);

  std::cout << "using default comparison:";
  std::stable_sort (myvector.begin(), myvector.end());
  for (std::vector<double>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  myvector.assign(mydoubles,mydoubles+8);

  std::cout << "using 'compare_as_ints' :";
  std::stable_sort (myvector.begin(), myvector.end(), compare_as_ints);
  for (std::vector<double>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

//Possible output:
//using default comparison: 1.32 1.41 1.62 1.73 2.58 2.72 3.14 4.67
//using 'compare_as_ints' : 1.41 1.73 1.32 1.62 2.72 2.58 3.14 4.67
  1. is_sorted(beg, end); // 返回一个 bool 值,指出整个输入序列是否有序
  2. is_sorted(beg, end, comp); // 返回一个 bool 值,指出整个输入序列是否有序
  • 示例
// is_sorted example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_sorted, std::prev_permutation
#include <array>        // std::array

int main () {
  std::array<int,4> foo {2,4,1,3};

  do {
    // try a new permutation:
    std::prev_permutation(foo.begin(),foo.end());

    // print range:
    std::cout << "foo:";
    for (int& x:foo) std::cout << ' ' << x;
    std::cout << '\n';

  } while (!std::is_sorted(foo.begin(),foo.end()));

  std::cout << "the range is sorted!\n";

  return 0;
}

//Output:
//foo: 2 3 4 1
//foo: 2 3 1 4
//foo: 2 1 4 3
//foo: 2 1 3 4
//foo: 1 4 3 2
//foo: 1 4 2 3
//foo: 1 3 4 2
//foo: 1 3 2 4
//foo: 1 2 4 3
//foo: 1 2 3 4
//the range is sorted!
  1. is_sorted_until(beg, end); // 在输入序列中査找最长初始有序子序列,并返回子序列的尾后迭代器
  2. is_sorted_until(beg, end, comp); // 在输入序列中査找最长初始有序子序列,并返回子序列的尾后迭代器
  3. partial_sort(beg, mid, end); // 排序 mid-beg 个元素。即,如果 mid-beg 等于 42,则此函数将值最小的 42 个元素有序放在序列前 42 个位置
  4. partial_sort(beg, mid, end, comp); // 排序 mid-beg 个元素。即,如果 mid-beg 等于 42,则此函数将值最小的 42 个元素有序放在序列前 42 个位置
  5. partial_sort_copy(beg, end, destBeg, destEnd); // 排序输入范围中的元素,并将足够多的已排序元素放到 destBeg 和 destEnd 所指示的序列中
  6. partial_sort_copy(beg, end, destBeg, destEnd, comp); // 排序输入范围中的元素,并将足够多的已排序元素放到 destBeg 和 destEnd 所指示的序列中
  7. nth_element(beg, nth, end); // nth 是一个迭代器,指向输入序列中第 n 大的元素。nth 之前的元素都小于等于它,而之后的元素都大于等于它
  8. nth_element(beg, nth, end, comp); // nth 是一个迭代器,指向输入序列中第 n 大的元素。nth 之前的元素都小于等于它,而之后的元素都大于等于它

Min/Max

  • 最小值和最大值,使用 < 运算符或给定的比较操作 comp 进行比较
  1. min(val1, va12); // 返回 val1 和 val2 中的最小值,两个实参的类型必须完全一致。参数和返回类型都是 const的引引用,意味着对象不会被拷贝。下略
  2. min(val1, val2, comp);
  3. min(init_list);
  4. min(init_list, comp);
  • 示例:
// min example
#include <iostream>     // std::cout
#include <algorithm>    // std::min

int main () {
  std::cout << "min(1,2)==" << std::min(1,2) << '\n';
  std::cout << "min(2,1)==" << std::min(2,1) << '\n';
  std::cout << "min('a','z')==" << std::min('a','z') << '\n';
  std::cout << "min(3.14,2.72)==" << std::min(3.14,2.72) << '\n';
  return 0;
}

//Output:
//min(1,2)==1
//min(2,1)==1
//min('a','z')==a
//min(3.14,2.72)==2.72
  1. max(val1, val2);
  2. max(val1, val2, comp);
  3. max(init_list);
  4. max(init_list, comp);
  5. minmax(val1, val2); // 返回一个 pair,其 first 成员为提供的值中的较小者,second 成员为较大者。下略
  6. minmax(vall, val2, comp);
  7. minmax(init_list);
  8. minmax(init_list, comp);
  • 示例:
// minmax example
#include <iostream>     // std::cout
#include <algorithm>    // std::minmax

int main () {
  auto result = std::minmax({1,2,3,4,5});

  std::cout << "minmax({1,2,3,4,5}): ";
  std::cout << result.first << ' ' << result.second << '\n';
  return 0;
}

//Output:
//minmax({1,2,3,4,5}): 1 5
  1. min_element(beg, end); // 返回指向输入序列中最小元素的迭代器
  2. min_element(beg, end, comp); // 返回指向输入序列中最小元素的迭代器
  3. max_element(beg, end); // 返回指向输入序列中最大元素的迭代器
  4. max_element(beg, end, comp); // 返回指向输入序列中最大元素的迭代器
  • 示例:
// min_element/max_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::min_element, std::max_element

bool myfn(int i, int j) { return i<j; }

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  // using default comparison:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';

  // using function myfn as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myfn) << '\n';

  // using object myobj as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myobj) << '\n';

  return 0;
}

// Output:
// The smallest element is 2
// The largest element is 9
// The smallest element is 2
// The largest element is 9
// The smallest element is 2
// The largest element is 
  1. minmax_element(beg, end); // 返回一个 pair,其中 first 成员为最小元素,second 成员为最大元素
  2. minmax_element(beg, end, comp); // 返回一个 pair,其中 first 成员为最小元素,second 成员为最大元素
// minmax_element
#include <iostream>     // std::cout
#include <algorithm>    // std::minmax_element
#include <array>        // std::array

int main () {
  std::array<int,7> foo {3,7,2,9,5,8,6};

  auto result = std::minmax_element (foo.begin(),foo.end());

  // print result:
  std::cout << "min is " << *result.first;
  std::cout << ", at position " << (result.first-foo.begin()) << '\n';
  std::cout << "max is " << *result.second;
  std::cout << ", at position " << (result.second-foo.begin()) << '\n';

  return 0;
}

//Output:
//min is 2, at position 2
//max is 9, at position 3
这篇关于C++STL笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!