C++STL笔记
作者:互联网
STL学习笔记
- 参考文档:
总体总结
- 容器分类
- 容器复合情况
String
- string是C++风格的字符串,而string本质上是一个类
string和char * 区别: - char * 是一个指针
- string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。
特点:
string 类内部封装了很多成员方法
例如:查找find,拷贝copy,删除delete 替换replace,插入insert
string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
构造函数
string();
//创建一个空的字符串 例如: string str;
string(const char* s);
//使用字符串s初始化string(const string& str);
//使用一个string对象初始化另一个string对象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
赋值操作
string& operator=(const char* s);
//char*类型字符串 赋值给当前的字符串string& operator=(const string &s);
//把字符串s赋给当前的字符串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
string& assign(const char *s);
//把字符串s赋给当前的字符串string& assign(const char *s, int n);
//把字符串s的前n个字符赋给当前的字符串string& assign(const string &s);
//把字符串s赋给当前字符串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
字符串拼接
string& operator+=(const char* str);
//重载+=操作符string& operator+=(const char c);
//重载+=操作符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
string& append(const char *s);
//把字符串s连接到当前字符串结尾string& append(const char *s, int n);
//把字符串s的前n个字符连接到当前字符串结尾string& append(const string &s);
//同operator+=(const string& str)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查找和替换
- 查找:查找指定字符串是否存在
- 替换:在指定的位置替换字符串
int find(const string& str, int pos = 0) const;
//查找str第一次出现位置,从pos开始查找int find(const char* s, int pos = 0) const;
//查找s第一次出现位置,从pos开始查找int find(const char* s, int pos, int n) const;
//从pos位置查找s的前n个字符第一次位置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
int rfind(const string& str, int pos = npos) const;
//查找str最后一次位置,从pos开始查找int rfind(const char* s, int pos = npos) const;
//查找s最后一次出现位置,从pos开始查找int rfind(const char* s, int pos, int n) const;
//从pos查找s的前n个字符最后一次位置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.
string& replace(int pos, int n, const string& str);
//替换从pos开始n个字符为字符串strstring& 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
int compare(const string &s) const;
//与字符串s比较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字符串存取
char& operator[](int n);
//通过[]方式取字符char& at(int n);
//通过at方法获取字符back
front
String插入和删除
string& insert(int pos, const char* s);
//插入字符串string& insert(int pos, const string& str);
//插入字符串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...
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.
push_back
swap
pop_back
String子串
- 从字符串中获取想要的子串
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
参考链接:
- https://cplusplus.com/reference/vector/vector/
- 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
: 判断容器是否为空 空返回truecapacity
: 容器的容量void resize (size_type n);
: 重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
void resize (size_type n, const value_type& val);
: 重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除max_size
: 容器能够装下的 maximum number of elementsreserve
: 减少vector在动态扩展容量时的扩展次数.reserve(int len);
,容器预留len个元素长度,预留位置不初始化,元素不可访问。
元素访问
operator[];
//返回索引idx所指的数据at(int idx);
//返回索引idx所指的数据front();
//返回容器中第一个数据元素back();
//返回容器中最后一个数据元素value_type* data() noexcept;
: 返回指向容器中第一个元素的指针,因为vector容器内存是连续的所以可以使用p[]访问
元素更改(赋值/插入/删除/互换元素)
vector& operator=(const vector &vec);
//重载等号操作符- 示例:
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拷贝赋值给本身。- 示例:
// 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);
//尾部插入元素elepop_back();
//删除最后一个元素insert(const_iterator pos, ele);
//迭代器指向位置pos插入元素eleinsert(const_iterator pos, int count,ele);
//迭代器指向位置pos插入count个元素ele- 示例:
// 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之间的元素- 示例:
// 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与本身的元素互换,实现两个容器内元素进行互换(两个容器对象都必须是相同的类型)- swap可用于收缩内存: vector
(v).swap(v); //匿名对象 - 例子:
- swap可用于收缩内存: vector
// 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(参数)来扩展容器- 参数: Position in the container where the new element is inserted.
- 返回值: 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不同的操作
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
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
: 判断容器是否为空 空返回truecapacity
: 容器的容量void resize (size_type n);
: 重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
void resize (size_type n, const value_type& val);
: 重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除max_size
: 容器能够装下的 maximum number of elementsreserve
: 减少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与本身的元素互换,实现两个容器内元素进行互换(两个容器对象都必须是相同的类型)- swap可用于收缩内存: vector
(v).swap(v); //匿名对象 - 例子:
- swap可用于收缩内存: vector
// 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(参数)来扩展容器- 参数: Position in the container where the new element is inserted.
- 返回值: 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)的数据结构,它有两个出口
构造函数:
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)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
构造函数
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)
获取元素
front
back
更改元素(同deque)
Operations
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
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
reverse
set/multiset
- https://cplusplus.com/reference/set/
- 所有元素都会在插入时自动被排序
- set/multiset属于关联式容器,底层结构是用二叉树实现。(or hashmap)
set和multiset区别:
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
构造函数
set<T> st;
//默认构造函数:set(const set &st);
//拷贝构造函数
插入和删除
insert
erase
swap
clear
emplace
emplace_hint
查找和统计
find
// //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count
// 统计key的元素个数
map
简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
优点: - 可以根据key值快速找到value值
构造函数和赋值
map<T1, T2> mp;
//map默认构造函数: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;
}
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(与上面同)
容量和大小(同)
获取元素
operator[]
at
更改元素
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
erase
swap
clear
emplace
emplace_hint
algorithm
Requirements
Header: <algorithm>
Namespace std
不更改序列的操作
简单查找算法,要求输入迭代器(input iterator)
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
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
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
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.
count_if(beg, end, unaryPred);
// 统计有多少个元素满足 unaryPredall_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.
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.
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)
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
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(前两个输入迭代器,后两个前向迭代器) 外,都要求两个前向迭代器
search(beg1, end1, beg2, end2);
// 返回第二个输入范围(子序列)在第一个输入范围中第一次出现的位置,未找到则返回 end1search(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
find_end(beg1, end1, beg2, end2);
// 类似 search,但返回的最后一次出现的位置。如果第二个输入范围为空,或者在第一个输入范围为空,或者在第一个输入范围中未找到它,则返回 end1find_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
find_first_of(beg1, end1, beg2, end2);
// 返回一个迭代器,指向第二个输入范围中任意元素在第一个范围中首次出现的位置,未找到则返回end1find_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
其他只读算法,传入输入迭代器
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
equal(beg1, end1, beg2);
// 比较每个元素,确定两个序列是否相等。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)中
- 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
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
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
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
transform(beg, end, dest, unaryOp);
// 调用给定操作(一元操作),并将结果写到dest中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
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
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
使用前向迭代器的写算法,要求前向迭代器
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
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
replace(beg, end, old_val, new_val);
// 用 new_val 替换等于 old_val 的每个匹配元素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)
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
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)
fill(beg, end, val);
// 将 val 赋予每个元素,返回 voidfill_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
genetate(beg, end, Gen);
// 每次调用 Gen() 生成不同的值赋予每个序列,返回 voidgenetate_n(beg, cnt, Gen);
// 每次调用 Gen() 生成不同的值赋予 cnt 个序列,返回指向写入到输出序列最有一个元素之后位置的迭代器
使用随机访问迭代器的重排算法
random_shuffle(beg, end);
// 混洗输入序列中的元素,返回 voidrandom_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
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
使用双向迭代器的重排算法
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
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 版本完成重拍后写入到指定目的序列中,而不改变输入序列
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
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
remove_copy(beg, end, dest, val);
// 通过用保留的元素覆盖要删除的元素实现删除 ==val 的元素,返回一个指向最后一个删除元素的尾后位置的迭代器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
unique(beg, end);
// 通过对覆盖相邻的重复元素(用 == 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置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
unique_copy(beg, end, dest);
// 通过对覆盖相邻的重复元素(用 == 确定是否相同)实现重排序列。返回一个迭代器,指向不重复元素的尾后位置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
rotate(beg, mid, end);
// 围绕 mid 指向的元素进行元素转动。元素 mid 成为为首元素,随后是 mid+1 到到 end 之前的元素,再接着是 beg 到 mid 之前的元素。返回一个迭代器,指向原来在 beg 位置的元素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算法
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
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)
partition_copy(beg, end, dest1, dest2, unaryPred);
// 将满足 unaryPred 的元素拷贝到到 dest1,并将不满足 unaryPred 的元素拷贝到到 dest2。返回一个迭代器 pair,其 first 成员表示拷贝到 dest1 的的元素的末尾,second 表示拷贝到 dest2 的元素的末尾。partitioned_point(beg, end, unaryPred);
// 输入序列必须是已经用 unaryPred 划分过的。返回满足 unaryPred 的范围的尾后迭代器。如果返回的迭代器不是 end,则它指向的元素及其后的元素必须都不满足 unaryPredstable_partition(beg, end, unaryPred);
// 使用 unaryPred 划分输入序列。满足 unaryPred 的元素放置在序列开始,不满足的元素放在序列尾部。返回一个迭代器,指向最后一个满足 unaryPred 的元素之后的位置如果所有元素都不满足 unaryPred,则返回 beg
Binary search(在分区/排序范围内操作)
- 二分搜索算法,传入前向迭代器或随机访问迭代器(random-access iterator),要求序列中的元素已经是有序的。通过小于运算符(<)或 comp 比较操作实现比较。
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.
lower_bound(beg, end, val);
// 返回一个非递减序列 [beg, end) 中的第一个大于等于值 val 的位置的迭代器,不存在则返回 endlower_bound(beg, end, val, comp);
// 返回一个非递减序列 [beg, end) 中的第一个大于等于值 val 的位置的迭代器,不存在则返回 endupper_bound(beg, end, val);
// 返回一个非递减序列 [beg, end) 中第一个大于 val 的位置的迭代器,不存在则返回 end
upper_bound(beg, end, val, comp); // 返回一个非递减序列 [beg, end) 中第一个大于 val 的位置的迭代器,不存在则返回 endequal_range(beg, end, val);
// 返回一个 pair,其 first 成员是 lower_bound 返回的迭代器,其 second 成员是 upper_bound 返回的迭代器
Merge(operating on sorted ranges)
merge(beg1, end1, beg2, end2, dest);
// 两个输入序列必须都是有序的,用 < 运算符将合并后的序列写入到 dest 中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
inplace_merge(beg, mid, end);
// 将同一个序列中的两个有序子序列合并为单一的有序序列。beg 到 mid 间的子序列和 mid 到 end 间的子序列被合并,并被写入到原序列中。使用 < 比较元素。inplace_merge(beg, mid, end, comp);
// 将同一个序列中的两个有序子序列合并为单一的有序序列。beg 到 mid 间的子序列和 mid 到 end 间的子序列被合并,并被写入到原序列中。使用给定的 comp 操作。
Sorting(排序算法)
- 要求随机访问迭代器(random-access iterator)
sort(beg, end);
// 排序整个范围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
stable_sort(beg, end);
// 排序整个范围(稳定排序)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
is_sorted(beg, end);
// 返回一个 bool 值,指出整个输入序列是否有序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!
is_sorted_until(beg, end);
// 在输入序列中査找最长初始有序子序列,并返回子序列的尾后迭代器is_sorted_until(beg, end, comp);
// 在输入序列中査找最长初始有序子序列,并返回子序列的尾后迭代器partial_sort(beg, mid, end);
// 排序 mid-beg 个元素。即,如果 mid-beg 等于 42,则此函数将值最小的 42 个元素有序放在序列前 42 个位置partial_sort(beg, mid, end, comp);
// 排序 mid-beg 个元素。即,如果 mid-beg 等于 42,则此函数将值最小的 42 个元素有序放在序列前 42 个位置partial_sort_copy(beg, end, destBeg, destEnd);
// 排序输入范围中的元素,并将足够多的已排序元素放到 destBeg 和 destEnd 所指示的序列中partial_sort_copy(beg, end, destBeg, destEnd, comp);
// 排序输入范围中的元素,并将足够多的已排序元素放到 destBeg 和 destEnd 所指示的序列中nth_element(beg, nth, end);
// nth 是一个迭代器,指向输入序列中第 n 大的元素。nth 之前的元素都小于等于它,而之后的元素都大于等于它nth_element(beg, nth, end, comp);
// nth 是一个迭代器,指向输入序列中第 n 大的元素。nth 之前的元素都小于等于它,而之后的元素都大于等于它
Min/Max
- 最小值和最大值,使用 < 运算符或给定的比较操作 comp 进行比较
min(val1, va12);
// 返回 val1 和 val2 中的最小值,两个实参的类型必须完全一致。参数和返回类型都是 const的引引用,意味着对象不会被拷贝。下略min(val1, val2, comp);
min(init_list);
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
max(val1, val2);
max(val1, val2, comp);
max(init_list);
max(init_list, comp);
minmax(val1, val2);
// 返回一个 pair,其 first 成员为提供的值中的较小者,second 成员为较大者。下略minmax(vall, val2, comp);
minmax(init_list);
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
min_element(beg, end);
// 返回指向输入序列中最小元素的迭代器min_element(beg, end, comp);
// 返回指向输入序列中最小元素的迭代器max_element(beg, end);
// 返回指向输入序列中最大元素的迭代器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
minmax_element(beg, end);
// 返回一个 pair,其中 first 成员为最小元素,second 成员为最大元素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
标签:std,end,cout,STL,笔记,int,vector,C++,include 来源: https://www.cnblogs.com/zranguai/p/16676150.html