1.string容器
a.本质
string的本质是一个类,string的类内封装了很多成员函数,例如查找find,拷贝copy,删除delete,替换replace,插入insert等。
b.string的构造函数
string();` //创建一个空的字符串 例如: string str;
`string(const char* s);` //使用字符串s初始化
* `string(const string& str);` //使用一个string对象初始化另一个string对象
* `string(int n, char c);` //使用n个字符c初始化
include <string>
//string构造
void test01()
{
string s1; //创建空字符串,调用无参构造函数
cout << "str1 = " << s1 << endl;
const char* str = "hello world";
string s2(str); //把c_string转换成了string
cout << "str2 = " << s2 << endl;
string s3(s2); //调用拷贝构造函数
cout << "str3 = " << s3 << endl;
string s4(10, 'a');
cout << "str3 = " << s3 << endl;
}
int main() {
test01();
system("pause");
return 0;
}
c.string的赋值操作
string& operator=(const char* s);` //char*类型字符串 赋值给当前的字符串
* `string& operator=(const string &s);` //把字符串s赋给当前的字符串
* `string& operator=(char c);` //字符赋值给当前的字符串
* `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赋给当前字符串
用等号,assign都可以对另一个string进行赋值。示例如下:
void test01()
{
string str1;
str1 = "hello world";
cout << "str1 = " << str1 << endl;
string str2;
str2 = str1;
cout << "str2 = " << str2 << endl;
string str3;
str3 = 'a';
cout << "str3 = " << str3 << endl;
string str4;
str4.assign("hello c++");
cout << "str4 = " << str4 << endl;
string str5;
str5.assign("hello c++",5);
cout << "str5 = " << str5 << endl;
string str6;
str6.assign(str5);
cout << "str6 = " << str6 << endl;
string str7;
str7.assign(5, 'x');
cout << "str7 = " << str7 << endl;
}
int main() {
test01();
system("pause");
return 0;
}
d.string字符串的拼接
实现在字符串的末尾拼接字符串,+=,append
* `string& operator+=(const char* str);` //重载+=操作符
* `string& operator+=(const char c);` //重载+=操作符
* `string& operator+=(const string& str);` //重载+=操作符
* `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个字符连接到字符串结尾
//字符串拼接
void test01()
{
string str1 = "我";
str1 += "爱玩游戏";
cout << "str1 = " << str1 << endl;
str1 += ':';
cout << "str1 = " << str1 << endl;
string str2 = "LOL DNF";
str1 += str2;
cout << "str1 = " << str1 << endl;
string str3 = "I";
str3.append(" love ");
str3.append("game abcde", 4);
//str3.append(str2);
str3.append(str2, 4, 3); // 从下标4位置开始 ,截取3个字符,拼接到字符串末尾
cout << "str3 = " << str3 << endl;
}
int main() {
test01();
system("pause");
return 0;
}
e.string的查找和替换
* 查找:find(左往右),rfind(右往左)查找指定字符串是否存在,找到返回找到字符串的起始位置,找不到返回-1
* 替换:在指定的位置替换字符串,replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串
* `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第一次出现位置
* `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& replace(int pos, int n, const string& str); ` //替换从pos开始n个字符为字符串str
* `string& replace(int pos, int n,const char* s); ` //替换从pos开始的n个字符为字符串s
//查找和替换
void test01()
{
//查找
string str1 = "abcdefgde";
int pos = str1.find("de");
if (pos == -1)
{
cout << "未找到" << endl;
}
else
{
cout << "pos = " << pos << endl;
}
pos = str1.rfind("de");
cout << "pos = " << pos << endl;
}
void test02()
{
//替换
string str1 = "abcdefgde";
str1.replace(1, 3, "1111");
cout << "str1 = " << str1 << endl;
}
int main() {
//test01();
//test02();
system("pause");
return 0;
}
f.string字符的比较
相等返回0,大于返回1,小于返回-1。compare
* `int compare(const string &s) const; ` //与字符串s比较
* `int compare(const char *s) const;` //与字符串s比较
//字符串比较
void test01()
{
string s1 = "hello";
string s2 = "aello";
int ret = s1.compare(s2);
if (ret == 0) {
cout << "s1 等于 s2" << endl;
}
else if (ret > 0)
{
cout << "s1 大于 s2" << endl;
}
else
{
cout << "s1 小于 s2" << endl;
}
}
int main() {
test01();
system("pause");
return 0;
}
g.string字符的存取
两种方式获得字符 [] 函数at
* `char& operator[](int n); ` //通过[]方式取字符
* `char& at(int n); ` //通过at方法获取字符
void test01()
{
string str = "hello world";
for (int i = 0; i < str.size(); i++)
{
cout << str[i] << " ";
}
cout << endl;
for (int i = 0; i < str.size(); i++)
{
cout << str.at(i) << " ";
}
cout << endl;
//字符修改
str[0] = 'x';
str.at(1) = 'x';
cout << str << endl;
}
int main() {
test01();
system("pause");
return 0;
}
h,string的插入和删除
对string字符串进行插入和删除,insert erase
* `string& insert(int pos, const char* s); ` //插入字符串
* `string& insert(int pos, const string& str); ` //插入字符串
* `string& insert(int pos, int n, char c);` //在指定位置插入n个字符c
* `string& erase(int pos, int n = npos);` //删除从Pos开始的n个字符
//字符串插入和删除
void test01()
{
string str = "hello";
str.insert(1, "111");
cout << str << endl;
str.erase(1, 3); //从1号位置开始3个字符
cout << str << endl;
}
int main() {
test01();
system("pause");
return 0;
}
注意插入和删除的起始下标都是从0开始的
h.从字符串中取得想要的字串
substr
string substr(int pos = 0, int n = npos) const;` //返回由pos开始的n个字符组成的字符串
//子串
void test01()
{
string str = "abcdefg";
string subStr = str.substr(1, 3);
cout << "subStr = " << subStr << endl;
string email = "hello@sina.com";
int pos = email.find("@");
string username = email.substr(0, pos);
cout << "username: " << username << endl;
}
int main() {
test01();
system("pause");
return 0;
}
I.string 总结
是个类 插入insert 删除erase 查找find rfind
替换replace 比较compare 获取[],at 拼接+= append
获取字串substr 赋值 = assign
2.vector容器(动态数组)
* `vector<T> v; ` //采用模板实现类实现,默认构造函数
* `vector(v.begin(), v.end()); ` //将v[begin(), end())区间中的元素拷贝给本身。
* `vector(n, elem);` //构造函数将n个elem拷贝给本身。
* `vector(const vector &vec);` //拷贝构造函数。
#include <vector>
void printVector(vector<int>& v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1; //无参构造
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int> v2(v1.begin(), v1.end());
printVector(v2);
vector<int> v3(10, 100);
printVector(v3);
vector<int> v4(v3);
printVector(v4);
}
int main() {
test01();
system("pause");
return 0;
}
vector的赋值操作 = assign
vector容量和大小 empty capacity size resize
vector插入和删除 push_back pop_back insert eraser
清空 clear
* 尾插 --- push_back
* 尾删 --- pop_back
* 插入 --- insert (位置迭代器)
* 删除 --- erase (位置迭代器)
* 清空 --- clear
vector的存取操作 [] at front back
* `at(int idx); ` //返回索引idx所指的数据
* `operator[]; ` //返回索引idx所指的数据
* `front(); ` //返回容器中第一个数据元素
* `back();` //返回容器中最后一个数据元素
vector互换容器 swap 用来收缩内存
//收缩内存
v.resize(3);
vector<int>(v).swap(v); //匿名对象
预留空间 reserve
总结:
push_back pop_back insert erase clear
[] at front back
= assign
size capacity empty
resize swap
3.deque容器(双端数组)
双端数组,可以对头端进行插入删除
**deque与vector区别:**
* vector对于头部的插入删除效率低,数据量越大,效率越低
* deque相对而言,对头部的插入删除速度回比vector快
* vector访问元素时的速度会比deque快,这和两者内部实现有关
deque内部工作原理:
deque内部有个**中控器**,维护每段缓冲区中的内容,缓冲区中存放真实数据
中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间
赋值 = assign
大小 empty size resize
插入和删除 insert erase push_back pop_back pop_front push_front
* 插入和删除提供的位置是迭代器!
* 尾插 --- push_back
* 尾删 --- pop_back
* 头插 --- push_front
* 头删 --- pop_front
deque数据的存取 [] at front back
- 除了用迭代器获取deque容器中元素,[ ]和at也可以
- front返回容器第一个元素
- back返回容器最后一个元素
排序 sort(iterator beg,iterator end ) 从低到高 头文件algorithm
4.stack容器(栈)
先进后出,入栈push 出栈 pop(删除)
赋值 =
数据存储 push pop top(拿到栈顶数据)
大小 size empty
* 入栈 --- push
* 出栈 --- pop
* 返回栈顶 --- top
* 判断栈是否为空 --- empty
* 返回栈大小 --- size
5.queue(队列)
先进先出 push(入队) pop(出队)
赋值 =
数据的存储 push pop back front
大小 size empty
没有迭代器 不支持随机访问
- 入队 --- push
- 出队 --- pop
- 返回队头元素 --- front
- 返回队尾元素 --- back
- 判断队是否为空 --- empty
- 返回队列大小 --- size
6.list(链表)
**链表**(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
链表的组成:链表由一系列**结点**组成
结点的组成:一个是存储数据元素的**数据域**,另一个是存储下一个结点地址的**指针域**
STL中的链表是一个双向循环链表
list的优点:
* 采用动态存储分配,不会造成内存浪费和溢出
* 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
* 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大
List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
赋值 = assign
交换 swap
大小 size empty resize
- 判断是否为空 --- empty
- 返回元素个数 --- size
- 重新指定个数 --- resize
插入和删除
* 尾插 --- push_back
* 尾删 --- pop_back
* 头插 --- push_front
* 头删 --- pop_front
* 插入 --- insert
* 删除 --- erase
* 移除 --- remove(删除容器中的值)
* 清空 --- clear
数据存取 front back 不可以用[] at
数据的反转 reverse reserve是预留空间
链表排序 sort(成员函数) 默认从小到大
v.sort(mycompare)指定规则
对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序
* 高级排序只是在排序规则上再进行一次逻辑规则制定,并不复杂
7.set/multiset(二叉树)
所有元素都会在插入时自动被排序
* set不允许容器中有重复的元素
* multiset允许容器中有重复的元素
赋值 =
set的大小和交换 size empty swap
插入和删除 insert erase clear
* 插入 --- insert
* 删除 --- erase
* 清空 --- clear
set查找和统计 find count
* find(key);` //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
* `count(key);` //统计key的元素个数
pair对组创建
pair<person,int>p(p1,6)
pair<person,int> p=make_pair(p1,6)