这几天简略的把《C++ primer plus》过一遍(不多,总共才936页( =•ω•= )),挑点书上有用的辅以网上查到的blog资料简单总结一下,以后再细学C++
———————————————————————————————————
一套很好的C++教程
一.C++杂项总结
(1)C++支持连续赋值,从右往左int n=x=b=c=10;
合法
(2)新的赋值方式:int n(32);std::cout<<n;
(3)用cout输出十进制、十六进制和八进制显示整数
C++ cout利用控制符dec、hex和oct,分别输出十进制、十六进制和八进制显示整数.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int chest=42;
int waist=42;
int inseam=42;
cout<<hex<<"waist="<<waist<<" (16/hexadecimal for 42)"<<endl;//十六进制
cout<<oct<<"inseam="<<inseam<<" (8/octal for 42)"<<endl;//八进制
cout<<dec<<"chest="<<chest<<" (10/decimal for 42)"<<endl;//十进制
}
输出:
waist=2a (16/hexadecimal for 42)
inseam=52 (8/octal for 42)
hest=42 (10/decimal for 42)
(4)puts("'");cout<<'\'';//(^_^)
(5)变量auto
如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置成与初始值相同;
auto n=100;//n is int ;
auto x=1.5;//x is double;
auto y=1.3e12L;//y is long double;
std::vector<double>v;
auto it=v.begin();//等同于 {std::vector<double>::iterator it=v.begin();}
(6) 偷个懒让编译器帮忙算
short things[]={1,5,8};
int num_elements=sizeof things/sizeof(short);
(7)
char s[4] {'h','i',112,'\0'};//allowed;112会转换成ASCII码所对应的字符
(8)C++11中新增的基于范围的for循环
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string planets []= { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto(a dwarf planet)" };
cout << "Here are the planets: \n ";
for (auto val : planets)//C++11才能用(没什么用)
cout << val << endl;
return 0;
}
(9)头文件cctype中的字符函数
函数名称 | 返回值 |
---|---|
isalnum() | 如果参数是字母或数字,该函数返回true |
isalpha() | 如果参数是字母,该函数返回true |
iscntrl() | 如果参数是控制字符,该函数返回true |
isdigit() | 如果参数是数字(0~9),该函数返回true |
isgraph() | 如果参数是除空格之外的打印字符,该函数返回true |
islower() | 如果参数是小写字母,该函数返回true |
isprint() | 如果参数是打印字符(包括空格),该函数返回true |
ispunct() | 如果参数是标点符号,该函数返回true |
isspace() | 如果参数是标准空白字符,如空格、进纸、换行符、回车、水平制表符或者垂直制表符,该函数返回true |
isupper() | 如果参数是大写字母,该函数返回true |
isxdigit() | 如果参数是十六进制数字,即09、af或A~F,该函数返回true |
tolower() | 如果参数是大写字符,则返回其小写,否则返回该参数 |
toupper() | 如果参数是小写字符,则返回其大写,否则返回该参数 |
(10)位运算详解+竞赛常见用法总结
二.内联函数
调用内联函数比调用普通函数更快但更消耗内存
inline int x()
{
.......
}
三. 引用变量
将temp作为rate变量的别名
int rate;
int & temp=rate;
temp与rate的地址会相同,值相同,操作后一块改变
#include <iostream>
#include <string>
using namespace std;
void add(int &x)//x和temp均为rate的引用变量,改变其中任意一个剩余的都会受其影响
{
x++;
cout<<x<<" "<<endl;
cout<<&x<<" "<<endl;
}
int main ()
{
int rate=100;
int & temp=rate;
rate++;
cout<<rate<<" "<<temp<<endl;
add(rate);
cout<<rate<<" "<<temp<<endl;
cout<<&rate<<" "<<&temp<<endl;
return 0;
}
输出:
101 101
102
0x6dfee8
102 102
0x6dfee8 0x6dfee8
引用变量适合用于结构体中
如果不希望函数修改传入的值,可以使用const避免失误void add(const int &x)
四.函数重载
函数重载是一种特殊情况,C++允许在同一作用域中声明几个类似的同名函数,这些同名函数的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
会自动选择,所以很🐂🍺
函数重载的详解
五.函数模板
template <typename AnyType>
二者完全相同,这里推荐使用前者,因为class作用很多容易弄混
template <class AnyType>
使用函数模板就再不用重新写一个函数了,省时省力
#include <iostream>
using namespace std;
template<typename T>
void Swap(T & x, T & y)
{
T tmp = x;
x = y;
y = tmp;
}
int main()
{
int n = 1, m = 2;
Swap(n, m); //编译器自动生成 void Swap (int &, int &)函数
double f = 1.2, g = 2.3;
Swap(f, g); //编译器自动生成 void Swap (double &, double &)函数
return 0;
}
(1)类模板
六.class类
类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例(Instance),拥有类的成员变量和成员函数。
有些教程将类的成员变量称为类的属性(Property),将类的成员函数称为类的方法(Method)。在面向对象的编程语言中,经常把函数(Function)称为方法(Method)。
与结构体一样,类只是一种复杂数据类型的声明,不占用内存空间。而对象是类这种数据类型的一个变量,或者说是通过类这种数据类型创建出来的一份实实在在的数据,所以占用内存空间。
(1)类的定义
类是用户自定义的类型,如果程序中要用到类,必须提前说明,或者使用已存在的类(别人写好的类、标准库中的类等),C++语法本身并不提供现成的类的名称、结构和内容。
类与结构体很类似!!
注意在类定义的最后有一个分号:
;
(2)完整示例
#include<iostream>
using namespace std;
typedef long long ll;
const ll N=1e5+7;
class Student
{
public :
//类所包含的成员变量
string name;//char *name;
ll age;
double score;
//类所包含的成员函数
void say()
{
cout<<name<<"'s age is "<<age<<" ,and his total score is "<<score<<"."<<endl;
}
};
int main()
{
Student *p = new Student;//用new来分配内存
Student stu;//创建对象
p->name = "Meng";
p->age = 19;
p->score = 97.5d;
p->say();
delete p;//释放内存
return 0;
}
(3)成员函数与成员变量
类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存。但是,在定义类的时候不能对成员变量赋值,因为类只是一种数据类型或者说是一种模板,本身不占用内存空间,而变量的值则需要内存来存储。
类的成员函数也和普通函数一样,都有返回值和参数列表,它与一般函数的区别是:成员函数是一个类的成员,出现在类体中,它的作用范围由类来决定;而普通函数是独立的,作用范围是全局的,或位于某个命名空间内。
成员函数最好放在类体里,如果放到外面必须要在函数名前面加上类名予以限定。
示例:
#include<iostream>
using namespace std;
typedef long long ll;
const ll N=1e5+7;
class Student{
public:
char *name;
int age;
float score;
void say(); //内联函数声明,可以增加 inline 关键字,但编译器会忽略
};
//函数定义
inline void Student::say()
{
cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
}
int main()
{
}
可以有这样的操作 但是不推荐
(4)public private
C++通过 public、protected、private
三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。所谓访问权限,就是你能不能使用该类中的成员。
C++ 中的 public、private、protected 只能修饰类的成员,不能修饰类,C++中的类没有共有私有之分。
在类的内部(定义类的代码内部),无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制。
在类的外部(定义类的代码之外),只能通过对象访问成员,并且通过对象只能访问 public 属性的成员,不能访问 private、protected 属性的成员。
#include <iostream>
using namespace std;
//类的声明
class Student{
private: //私有的
string m_name;
int m_age;
double m_score;
public: //共有的
void setname(string name);
void setage(int age);
void setscore(double score);
void show();
};
//成员函数的定义
void Student::setname(string name){
m_name = name;
}
void Student::setage(int age){
m_age = age;
}
void Student::setscore(double score){
m_score = score;
}
void Student::show(){
cout<<m_name<<"'s age is "<<m_age<<" ,and his total score is "<<m_score<<"."<<endl;
}
int main()
{
Student stu;
stu.setname("Meng");
stu.setage(19);
stu.setscore(97.5d);
stu.show();
return 0;
}
根据C++软件设计规范,实际项目开发中的成员变量以及只在类内部使用的成员函数(只被成员函数调用的成员函数)都建议声明为
private,而只将允许通过对象调用的成员函数声明为 public。
成员变量大都以m_开头,这是约定成俗的写法,不是语法规定的内容。以m_开头既可以一眼看出这是成员变量,又可以和成员函数中的形参名字区分开。
给成员变量赋值的函数通常称为 set 函数,它们的名字通常以set开头,后跟成员变量的名字;读取成员变量的值的函数通常称为 get 函数,它们的名字通常以get开头,后跟成员变量的名字。
所谓封装,是指尽量隐藏类的内部实现,只向用户提供有用的成员函数。
(5)构造函数
方便class的赋值
大致由三个部分组成
public:
//声明构造函数
Student(string name, int age, float score);
//声明普通成员函数
void show();
Student::Student(string name, int age, float score){
m_name = name;
m_age = age;
m_score = score;
}
Student stu("Meng", 19, 97.5f);
构造函数的重载
构造函数详解
(6)this指针
this 只能用在类的内部,通过 this 可以访问类的所有成员,包括 private、protected、public 属性的。
本例中成员函数的参数和成员变量重名,只能通过 this 区分。如:this -> name = name;
注意this是一个const指针
void Student::printThis(){
cout<<this<<endl;
}
Student *pstu1 = new Student;
pstu1 -> printThis();
cout<<pstu1<<endl;
输出的是地址
详解
(7)友元函数
借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。友元函数可以访问当前类中的所有成员,包括 public、protected、private 属性的。
注意,友元函数不同于类的成员函数,在友元函数中不能直接访问类的成员,必须要借助对象。
详解
七.重载运算符
运算符重载是通过函数实现的,它本质上是函数重载。
(1)类的重载运算符
类的重载+运算符,要在类里声明
........
public:
void display() const;
//声明为友元函数
friend complex operator+(const complex &A, const complex &B);
........
//在全局范围内重载+
complex operator+(const complex &A, const complex &B){
complex C;
C.m_real = A.m_real + B.m_real;
C.m_imag = A.m_imag + B.m_imag;
return C;
}
当执行c3 = c1 + c2;
语句时,编译器检测到+号两边都是 complex 对象,就会转换为类似下面的函数调用: c3 = operator+(c1, c2);
(2)结构体的重载运算符
本题要求总分相同的,约定编号较小的选手排名靠前。可以在结构体内直接重载运算符<。
struct person
{
ll s,idx,w;
bool operator<(const person &t)const
{
if(t.s!=s)return s>t.s;
return idx<t.idx;
}
}p[N],loser[N],winer[N];
重载运算符<以后直接sort即可实现
sort(p+1,p+1+2*n);
(3)重载限制
多数C++运算符都可以重载。但是还存在着一些限制。
- 重载后的运算符必须至少有一个操作数是用户自定义的类型,这将防止用户为标准类型重载运算符。
- 使用运算符时不能违反运算原来的句法规则。
- 不能创造新的运算符。
- 不能重载下面的这些运算符。
sizeof sizeof运算符
.: 成员运算符
.* 成员指针运算符
:: 作用域解析运算符
?: 条件运算符
typeid 一个RTTI运算符
const_cast 强制类型转换运算符
dynamic_cast 强制类型转换运算符
reinterpret_cast 强制类型转换运算符
static_cast 强制类型转换运算符
大多数运算符都可以通过成员或非成员函数进行重载,但这些运算符只能通过成员函数进行重载:
= 赋值运算符
() 函数调用运算符
[] 下标运算符
-> 通过指针访问类成员的运算符
八.string常用函数总结
(1)字符串的比较
1. C ++字符串支持常见的比较操作符>,>=,<,<=,==,!=
,甚至支持string与C-string的比较如 str<”hello”
。
在使用>,>=,<,<=
这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小,
比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
同时,string (“aaaa”) <string(aaaaa)
。
2. 另一个功能强大的比较函数是成员函数compare()
。他支持多参数处理,支持用索引值和长度定位子串来进行比较。
他返回一个整数来表示比较结果,返回值意义如下:0:相等 1:大于 -1:小于 (A的ASCII码是65,a的ASCII码是97,0的ASCII码是48)
(2). string的插入:push_back() 和 insert()
void test4()
{
string s1;
// 尾插一个字符
s1.push_back('a');
s1.push_back('b');
s1.push_back('c');
cout<<"s1:"<<s1<<endl; // s1:abc
// insert(pos,char):在制定的位置pos前插入字符char
s1.insert(s1.begin(),'1');
cout<<"s1:"<<s1<<endl; // s1:1abc
}
输出:
s1:abc
s1:1abc
(3)字符串的拼接append()/直接+
append函数是向string的后面追加字符或字符串。
string支持直接s1+=s2;
1.向string的后面加string的一部分
string s1 = “hello “, s2 = “wide world “;
s1.append(s2, 5, 5); ////把字符串s2中从5开始的5个字符连接到当前字符串的结尾
s1 = “hello world”;
string str1 = “hello “, str2 = “wide world “;
str1.append(str2.begin()+5, str2.end()); //把s2的迭代器begin()+5和end()之间的部分连接到当前字符串的结尾
str1 = “hello world”;
2.向string后面加多个字符
string s1 = “hello “;
s1.append(4,’!’); //在当前字符串结尾添加4个字符!
s1 = “hello !!!!”;
3.用append()和"+"
string s1 = “hello “; string s2 = “wide “; string s3 = “world “;
s1.append(s2); s1 += s3; //把字符串s连接到当前字符串的结尾
s1 = “hello wide “; s1 = “hello wide world “;
(4) string的删除:erase()
1. iterator erase(iterator p);//删除字符串中p所指的字符
2. iterator erase(iterator first, iterator last);//删除字符串中迭代器
区间[first,last)上所有字符
3. string& erase(size_t pos = 0, size_t len = npos);//删除字符串中从索引
位置pos开始的len个字符
4. void clear();//删除字符串中所有字符
void test6()
{
string s1 = "123456789";
// s1.erase(s1.begin()+1); // 结果:13456789
// s1.erase(s1.begin()+1,s1.end()-2); // 结果:189
s1.erase(1,6); // 结果:189
string::iterator iter = s1.begin();
while( iter != s1.end() )
{
cout<<*iter;
*iter++;
}
cout<<endl;
}
(5)string的查找:find
1. size_t find (constchar* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找子串s,返回找到的位置索引,
-1表示查找不到子串
2. size_t find (charc, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找字符c,返回找到的位置索引,
-1表示查找不到字符
3. size_t rfind (constchar* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,反向查找子串s,返回找到的位置索引,
-1表示查找不到子串
4. size_t rfind (charc, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,反向查找字符c,返回找到的位置索引,-1表示查找不到字符
5. size_tfind_first_of (const char* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找子串s的字符,返回找到的位置索引,-1表示查找不到字符
6. size_tfind_first_not_of (const char* s, size_t pos = 0) const;
//在当前字符串的pos索引位置开始,查找第一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
7. size_t find_last_of(const char* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,查找最后一个位于子串s的字符,返回找到的位置索引,-1表示查找不到字符
8. size_tfind_last_not_of (const char* s, size_t pos = npos) const;
//在当前字符串的pos索引位置开始,查找最后一个不位于子串s的字符,返回找到的位置索引,-1表示查找不到子串
void test8()
{
string s("dog bird chicken bird cat");
//字符串查找-----找到后返回首字母在字符串中的下标
// 1. 查找一个字符串
cout << s.find("chicken") << endl; // 结果是:9
// 2. 从下标为6开始找字符'i',返回找到的第一个i的下标
cout << s.find('i',6) << endl; // 结果是:11
// 3. 从字符串的末尾开始查找字符串,返回的还是首字母在字符串中的下标
cout << s.rfind("chicken") << endl; // 结果是:9
// 4. 从字符串的末尾开始查找字符
cout << s.rfind('i') << endl; // 结果是:18-------因为是从末尾开始查找,所以返回第一次找到的字符
// 5. 在该字符串中查找第一个属于字符串s的字符
cout << s.find_first_of("13br98") << endl; // 结果是:4---b
// 6. 在该字符串中查找第一个不属于字符串s的字符------先匹配dog,然后bird匹配不到,所以打印4
cout << s.find_first_not_of("hello dog 2006") << endl; // 结果是:4
cout << s.find_first_not_of("dog bird 2006") << endl; // 结果是:9
// 7. 在该字符串最后中查找第一个属于字符串s的字符
cout << s.find_last_of("13r98") << endl; // 结果是:19
// 8. 在该字符串最后中查找第一个不属于字符串s的字符------先匹配t--a---c,然后空格匹配不到,所以打印21
cout << s.find_last_not_of("teac") << endl; // 结果是:21
}
(6)string的分割/截取字符串:strtok() & substr()
strtok();
:分割字符串
void test10()
{
char str[] = "I,am,a,student; hello world!";
const char *split = ",; !";
char *p2 = strtok(str,split);
while( p2 != NULL )
{
cout<<p2<<endl;
p2 = strtok(NULL,split);
}
}
substr();
void test11()
{
string s1("0123456789");
string s2 = s1.substr(2,5); // 结果:23456-----参数5表示:截取的字符串的长度
cout<<s2<<endl;
}
(7)string的字符替换:replace
算法
replace
函数包含于头文件#include<string>
中。
/*用法一: *用str替换指定字符串从起始位置pos开始长度为len的字符 *string& replace (size_t pos, size_t len, const string& str); */
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.find("@"), 1, ""); //从第一个@位置替换第一个@为空
cout << line << endl;
return 0;
}
运行结果:
2.
/*用法二: *用str替换 迭代器起始位置 和 结束位置 的字符 *string& replace (const_iterator i1, const_iterator i2, const string& str); */
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.begin(), line.begin()+6, ""); //用str替换从begin位置开始的6个字符
cout << line << endl;
return 0;
}
运行结果:
3.
/*用法三: *用substr的指定子串(给定起始位置和长度)替换从指定位置上的字符串 *string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen); */
int main()
{
string line = "this@ is@ a test string!";
string substr = "12345";
line = line.replace(0, 5, substr, substr.find("1"), 3); //用substr的指定子串(从1位置数共3个字符)替换从0到5位置上的line
cout << line << endl;
return 0;
}
运行结果:
4.
/*用法八: *用重复n次的c字符替换从指定位置pos长度为len的内容 *string& replace (size_t pos, size_t len, size_t n, char c); */
int main()
{
string line = "this@ is@ a test string!";
char c = '1';
line = line.replace(0, 9, 3, c); //用重复3次的c字符替换从指定位置0长度为9的内容
cout << line << endl;
return 0;
}
运行结果:
5.
/*用法九: *用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)的内容 *string& replace (const_iterator i1, const_iterator i2, size_t n, char c); */
int main()
{
string line = "this@ is@ a test string!";
char c = '1';
line = line.replace(line.begin(), line.begin()+9, 3, c); //用重复3次的c字符替换从指定迭代器位置的内容
cout << line << endl;
return 0;
}
运行结果:
注:所有使用迭代器类型的参数不限于string类型,可以为vector、list等其他类型迭代器。
九.STL标准模板库
(1)for_each()
函数
可将代码:
vector<Review>::iterator pr;
for(pr=book.begin();pr!=book.end();pr++)
ShowReview(*pr);
替换为:
for_each(book.begin(),book.end(),ShowReview);
(2)random_shuffle()
函数,随机重新排序
STL中的函数random_shuffle()
用来对一个元素序列进行重新排序(随机的),函数原型如下:
template<class RandomAccessIterator>
void random_shuffle(
RandomAccessIterator _First, //指向序列首元素的迭代器
RandomAccessIterator _Last //指向序列最后一个元素的下一个位置的迭代器
);
#include <bits/stdc++.h>
using namespace std;
int main()
{
char b[]="abcde";
char a[10];
cout<<"char:"<<endl;
for(int i=0;i<10;i++)
{
strcpy(a,b);
random_shuffle(a,a+5);
cout<<a<<endl;
}
int c[]={1,2,3,4,5};
int d[10];
cout<<endl<<"int:"<<endl;
for(int i=0;i<10;i++)
{
memcpy(d,c,sizeof(c));
random_shuffle(d,d+5);
for(int j=0;j<5;j++) cout<<d[j]<<" ";
cout<<endl;
}
}
输出:
(3)STL算法
函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了相当多的有用算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。
STL提供了大约100个实现算法的模版函数,比如算法for_each
将为指定序列中的每一个元素调用指定的函数,stable_sort
以你所指定的规则对序列进行稳定性排序等等。只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。算法部分主要由头文件<algorithm>
,<numeric>
和<functional>
组成。
<algorithm>
是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
<numeric>
体积很小,只包括几个在序列上面进行简单数***算的模板函数,包括加法和乘法在序列上的一些操作。
<functional>
中则定义了一些模板类,用以声明函数对象。
STL中算法大致分为四类:
- 非可变序列算法:指不直接修改其所操作的容器内容的算法。
- 可变序列算法:指可以修改它们所操作的容器内容的算法。
- 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
- 数值算法:对容器内容进行数值计算。
C++ 各种迭代器
InputIterator
是用于输入的Iterator
OutputIterator
是用于输出的Iterator
ForwardIterator
是InputIterator,同时可以保证++
运算不会使之失效
RandomIterator
是ForwardIterator
,同时具有+,-,+=,-=
等运算及各种比较操作
以下对所有算法进行细致分类并标明功能:
1.查找算法(13个):判断容器中是否包含某个值
adjacent_find:
在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的ForwardIterator。否则返回last。重载版本使用输入的二元操作符代替相等的判断。
binary_search:
在有序序列中查找value,找到返回true。重载的版本实用指定的比较函数对象或函数指针来判断相等。
count:
利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。
count_if:
利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数。
equal_range:
功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound。
find:
利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的一个InputIterator。
find_end:
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代替等于操作。
find_first_of:
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使用了用户自定义操作符。
find_if:
使用输入的函数代替等于操作符执行find。
lower_bound:
返回一个ForwardIterator,指向在有序序列范围内的可以插入指定值而不破坏容器顺序的第一个位置。重载函数使用自定义比较操作。
upper_bound:
返回一个ForwardIterator,指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志一个大于value的值。重载函数使用自定义比较操作。
search:
给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位置,查找失败指向last1。重载版本使用自定义的比较操作。
search_n:
在指定范围内查找val出现n次的子序列。重载版本使用自定义的比较操作。
2.排序和通用算法(14个):提供元素排序策略
inplace_merge:
合并两个有序序列,结果序列覆盖两端范围。重载版本使用输入的操作进行排序。
merge:
合并两个有序序列,存放到另一个序列。重载版本使用自定义的比较。
nth_element:
将范围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。重载版本使用自定义的比较操作。
partial_sort:
对序列做部分排序,被排序元素个数正好可以被放到范围内。重载版本使用自定义的比较操作。
partial_sort_copy:
与partial_sort
类似,不过将经过排序的序列复制到另一个容器。
partition:
对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。
random_shuffle:
对指定范围内的元素随机调整次序。重载版本输入一个随机数产生操作。
reverse:
将指定范围内元素重新反序排序。
reverse_copy:
与reverse类似,不过将结果写入另一个容器。
rotate:
将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。
rotate_copy:
与rotate类似,不过将结果写入另一个容器。
sort:
以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
stable_sort:
与sort类似,不过保留相等元素之间的顺序关系。
stable_partition:
与partition类似,不过不保证保留容器中的相对顺序。
3.删除和替换算法(15个)
copy:
复制序列
copy_backward:
与copy
相同,不过元素是以相反顺序被拷贝。
iter_swap:
交换两个ForwardIterator的值。
remove:
删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove
和remove_if
函数。
remove_copy:
将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置。
remove_if:
删除指定范围内输入操作结果为true的所有元素。
remove_copy_if:
将所有不匹配元素拷贝到一个指定容器。
replace:
将指定范围内所有等于vold的元素都用vnew代替。
replace_copy:
与replace类似,不过将结果写入另一个容器。
replace_if:
将指定范围内所有操作结果为true的元素用新值代替。
replace_copy_if:
与replace_if
,不过将结果写入另一个容器。
swap:
交换存储在两个对象中的值。
swap_range:
将指定范围内的元素与另一个序列元素值进行交换。
unique:
清除序列中重复元素,和remove
类似,它也不能真正删除元素。重载版本使用自定义比较操作。
unique_copy:
与unique类似,不过把结果输出到另一个容器。
4.排列组合算法(2个):提供计算给定集合按一定顺序的所有可能排列组合
next_permutation:
取出当前范围内的排列,并重新排序为下一个排列。重载版本使用自定义的比较操作。
prev_permutation:
取出指定范围内的序列并将它重新排序为上一个序列。如果不存在上一个序列则返回false。重载版本使用自定义的比较操作。
5.算术算法(4个)
accumulate:
iterator对标识的序列段元素之和,加到一个由val指定的初始值上。重载版本不再做加法,而是传进来的 二元操作符被应用到元素上。
partial_sum:
创建一个新序列,其中每个元素值代表指定范围内该位置前所有元素之和。重载版本使用自定义操作代替加法。
inner_product:
对两个序列做内积(对应元素相乘,再求和)并将内积加到一个输入的初始值上。重载版本使用用户定义的操作。
adjacent_difference:
创建一个新序列,新序列中每个新值代表当前元素与上一个元素的差。重载版本用指定二元操作计算相邻元素的差。
7.生成和异变算法(6个)
fill:
将输入值赋给标志范围内的所有元素。
fill_n:
将输入值赋给first到first+n范围内的所有元素。
for_each:
用指定函数依次对指定范围内所有元素进行迭代访问,返回所指定的函数类型。该函数不得修改序列中的元素。
generate:
连续调用输入的函数来填充指定的范围。
generate_n:
与generate函数类似,填充从指定iterator开始的n个元素。
transform:
将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一个元素来自输入的另外一个序列。结果输出到指定容器。
7.关系算法(8个)
equal:
如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操作符。
includes:
判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回true。重载版本使用用户输入的函数。
lexicographical_compare:
比较两个序列。重载版本使用用户自定义比较操作。max: 返回两个元素中较大一个。重载版本使用自定义比较操作。max_element: 返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。
min:
返回两个元素中较小一个。重载版本使用自定义比较操作。
min_element:
返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。
mismatch:
并行比较两个序列,指出第一个不匹配的位置,返回一对iterator,标志第一个不匹配元素位置.如果都匹配,返回每个容器的last。重载版本使用自定义的比较操作。
8.集合算法(4个)
set_union:
构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。
set_intersection:
构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。
set_difference:
构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用自定义的比较操作。
set_symmetric_difference:
构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。
9.堆算法(4个)
make_heap:
把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
pop_heap:
并不真正把最大元素从堆中弹出,而是重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。
push_heap:
假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把元素插入容器后。重载版本使用指定的比较操作。
sort_heap:
对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。
(4)仿函数
注:如果您通过本文,有(qi)用(guai)的知识增加了,请您点个赞再离开,如果不嫌弃的话,点个关注再走吧,日更博主每天在线答疑 ! 当然,也非常欢迎您能在讨论区指出此文的不足处,作者会及时对文章加以修正 !如果有任何问题,欢迎评论,非常乐意为您解答!( •̀ ω •́ )✧