后台开发核心技术与应用实践读书笔记(三)
第3章 常用的STL使用
3.1 STL是什么
STL是一个标准模板库,是一个高效的C++程序库
3.2 string
-
使用strlen、strcpy、strcat、strcmp等,注意判NULL
下面是一道面试题
#include "stdafx.h" #include <string.h> class String { public: //一般写出下面四个即可 String(const char *str = NULL);// 普通构造函数 String(const String &other);// 拷贝构造函数 ~String(void);// 析构函数 String & operator = (const String &other);// 赋值函数 String & operator +(const String &other);//字符串相连 bool operator ==(const String &other);//判断相等 int getLength(); private: char *m_data;// 用于保存字符串 }; //普通构造函数 String::String(const char *str) { if (str == NULL) { m_data = new char[1];// 得分点:对空字符串自动申请存放结束标志'\0'的,加分点:对m_data加NULL判断 *m_data = '\0'; } else { int length = strlen(str); m_data = new char[length + 1];// 若能加 NULL 判断则更好 strcpy(m_data, str); } } // String的析构函数 String::~String(void) { delete[] m_data; // 或delete m_data; } //拷贝构造函数 String::String(const String &other)// 得分点:输入参数为const型 { if (!other.m_data)//对m_data加NULL判断 m_data = 0; int length = strlen(other.m_data); m_data = new char[length + 1];// 若能加 NULL 判断则更好 strcpy(m_data, other.m_data); } //赋值函数 String & String::operator = (const String &other) // 得分点:输入参数为const型 { if (this == &other)//得分点:检查自赋值 return *this; if (m_data) delete[] m_data;//得分点:释放原有的内存资源 int length = strlen(other.m_data); m_data = new char[length + 1];//加分点:对m_data加NULL判断 strcpy(m_data, other.m_data); return *this;//得分点:返回本对象的引用 } //字符串相连 String & String::operator +(const String &other){ String newStr; if (!other.m_data) newStr = *this; else if (!m_data) newStr = other; else { newStr.m_data = new char[strlen(m_data) + strlen(other.m_data + 1]; strcpy(newStr.m_data, m_data); strcat(newStr.m_data, other.m_data); } } //判断相等 bool String::operator ==(const String &other){ if (strlen(m_data) != strlen(other.m_data)) return false; else return strcmp(m_data, other.m_data) ? false : true; } //返回长度 int String::getLength(){ return strlen(m_data); }
当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数
-
C++字符串和C字符串的转换:data()以字符形式返回字符串内容,但不添加’\0\;c_str()返回一个以’\0’结尾的字符数组;copy()把字符串内容复制或写入既有的c_string或字符数组内。
-
string和int互转
-
string转int,采用的是标准库中的atoi函数
std::string str = "123"; int n = atoi(str.c_str()); cout<<n; //123
-
int转string ;C++11中的std::to_string;
-
-
常用成员函数:capacity()、max_size()、size()、length()、empty()、resize()
3.3 vector
-
容器大小size()指元素个数,容量capacity()指分配的内存大小
-
遍历:
for(int i=0;i<a.size();++i
、for(iter=ivector.begin();iter!=ivector.end();iter++)
、for_each
void print(n){ cout << n << " "; } //main函数 for_each(nums.begin(), nums.end(),print);//最后一种遍历方式
-
查找find()、删除erase()/pop_back()、增加insert()/push_front(),注意for 循环遍历删除时的坑:for语句条件里删除元素时,返回值指向已删除元素的下一个位置,不是删除元素时则直接++
//错误 for (vector<int>::iterator iter = veci.begin(); iter != veci.end(); iter++){ if (*iter == 3) veci.erase(iter); } //正确 for (vector<int>::iterator iter = veci.begin(); iter != veci.end();){ if (*iter == 3) veci.erase(iter); else iter++; }
-
reserve()提前设定容量大小;swap()强行释放vector所占内存`v.swap(vector());
3.4 map
-
map 是什么
- 本质:关联容器、键值对应、内部是一颗红黑树(非严格意义上的平衡二叉树)
- 功能:自动建立Key-Value 一一对应
-
map的查增删
- 插入:数据方式插入,会被覆盖原有数据(hashtable不一样)
- 删除问题与数组类似
-
map原理
-
红黑树,一种二叉查找树,logn的高度,时间复杂度是O(logn);
性质
- 每个节点要么是红得要么是黑的
- 根节点是黑的
- 每个叶子节点是黑的
- 如果一个节点是红的,那么它的两个儿子都是黑的
- 对于任意节点而言,其到叶节点尾端NIL指针的每条路径都包含相同数目的黑节点
操作:
- 左旋
- 右旋
-
3.5 set
set 、multiset、map、multimap 都是红黑树结构,红黑树的统计性能好与一般的平衡二叉树
注意的问题:
-
map和set 插入删除效率比其他序列容器高
- 关联容器不需要做内存拷贝和内存移动
- 一切操作都是指针换来换去与内存移动没有关系
-
为何每次插入之后,一千保存的iterator不会失效
- iterator相当于指向节点的指针,内存没有变,指向内存的指针不会失效(当然被删除的那个元素本身已经失效了)
-
当数据元素增多时,插入与搜索速率怎么变化
数据量增大一倍时,搜索次数也不过多了1次;