string 介绍

标志库类型

类型说明
string 字符char*
vector 动态数组静态数组[]
map key/value内部以树的形式存储 O(log2N) 哈希表 O(1)

string 介绍

  • string 类型支持长度可变的字符串,C++ 标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作
  • typedef basic_string<char> string; 模板类
  • typedef basic_string<wchar_t wstring; 模板类
  • 要使用 string 类型对象,必须包含相关头文件 #include<string> using std::string

string 对象的定义和初始化

  • string s1; // 默认构造函数,s1 为空串
  • steing s2(s1) // 将 s2 初始化为 s1 的一个副本
  • string s3("value"); // 将 s3 初始化为一个字符串字面值副本
  • string s4(n,'c'); // 将 s4 初始化为字符串 ‘c’ 的 n 个副本
  • 更多的见例子
 string s1;
string s2("abcdefghijkl");
cout << s2 << endl;
basic_string<char> s3("xxx"); //等价于 string s3("xxx")
cout << s3 << endl;
string s4("abcdefg",4);
cout << s4 << endl;
string s5(s2,3,6);
cout << s5 << endl;
string s6(4, 'A');
cout << s6 << endl;

string::iterator first = s2.begin() + 1;
// string::iterator last = s2.end();
string::iterator last = s2.begin() + 3;
string s7(first, last); //[first, lasr) 左闭右开
cout << s7 << endl;
// 输出结果
/*
abcdefghijkl
xxx
abcd
defghi
AAAA
bc
*/

常用的成员函数

成员函数功能描述
size()得到字符串大小
lentgh()同上
empty()判断是否为空
substr()截取字符串
find()在字符串中查找字符或者字符串
rfind()反向查找
replace()替代
compare()比较字符串
insert()插入字符
append()追加字符串
swap()交换字符串
重载运算符[],+=,=,+,>,>=,<,<=,!=,==,>>,<<等
int main(void)
{
string s1("abcdefdg");
cout << "s1.size() = " << s1.size()<<endl;
cout << "s1.length() = " << s1.length() << endl;
cout << s1.empty() << endl;

cout << s1.substr(1,2) << endl; // s1 本身不发生变化
cout << s1.substr(1) << endl; // 第2个参数默认是 nppos值为-1

string::size_type pos = s1.find('d', 1); // s1.rfind('d',2)
if (pos == string::npos)
cout << "not found" << endl;
else
cout << "pos = " << pos << endl;
pos = s1.rfind('d', 5);
if (pos == string::npos)
cout << "not found" << endl;
else
cout << "pos = " << pos << endl;

return 0;
}
/* 输出结果
s1.size() = 8
s1.length() = 8
0
bc
bcdefdg
pos = 3
pos = 3
*/
int main(void)
{
string s1("abcdefghijkl");
s1.replace(2,2,"AAAAAA");
cout << s1 << endl;

s1 = "abcdefg";
s1.replace(s1.begin()+1, s1.begin() + 4, "BBBBB");
cout << s1 << endl;

string s2 = "xyzabc";
s2.insert(2,"MMMM");
cout << s2 << endl;
s2.append("6666");
cout << s2 << endl;

string s3 = "111";
s2.swap(s3);
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
return 0;
}
/*
abAAAAAAefghijkl
aBBBBBefg
xyMMMMzabc
xyMMMMzabc6666
s2 = 111
s3 = xyMMMMzabc6666
*/
void fun(char *str)
{
cout << str << endl;
}

int main(void)
{
string s1 = "abc";
s1[1] = 'B';
cout << s1 << endl;
// const string s2 = "xyz";
// s2[1] = 'Y'; // error 非法的 不能给常量赋值 s2[1]返回的是 const char&
// string s3 = "111" + "222" + s1; // error 前两个至少有一个是对象
string s3 = "111" + s1 + "222" ;
cout << s3 << endl;

// fun(s3); // 必须把 string 转换为 char*
// s3.c_str(); //返回的是 const char*
// fun(s3.c_str()); // error 不能将 const char* 转换为 char*
fun(const_cast<char*>(s3.c_str()));

return 0;
}
/*
aBc
111aBc222
111aBc222
*/
  • find_first_of 和 find_last_of
  • find_first_not_of 和 find_last_not_of
  • 可以实现一个字符串去除左右空格


#include <string>
#include <iostream>
using namespace std;

int main(void)
{
string strinfo = "//*---Hello World!......------";
string strset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string::size_type first = strinfo.find_first_of(strset);
if(first == string::npos)
cout << "not find any characters" << endl;
string::size_type last = strinfo.find_last_of(strset);
if (last == string::npos)
cout << "not find any characters" << endl;
cout << strinfo.substr(first, last - first + 1) << endl;
return 0;
}
static void LTrim(string& s); // 去除左空格
static void RTrim(string& s); // 去除右空格
static void Trim(string& s); // 去除左右空格

void StringUtil::LTrim(string &s)
{
string drop = " \t";
// 找到第一个不是空格的位置 find_first_not_of
s.erase(0, s.find_first_not_of(drop)); //去掉第一个不是空格位置之前的东西
}

void StringUtil::RTrim(string &s)
{
string drop = " \t";
s.erase(s.find_last_not_of(drop) + 1);

}

void StringUtil::Trim(string &s)
{
LTrim(s);
RTrim(s);

}
// 去除左右空格
int main(void)
{
string s = " abcd ";
StringUtil::LTrim(s);
cout << "[" << s << "]" << endl;
s = " abcd ";
StringUtil::RTrim(s);
cout << "[" << s << "]" << endl;
s = " abcd ";
StringUtil::Trim(s);
cout << "[" << s << "]" << endl;
return 0;
}

vector 介绍

vector 介绍

  • vector 是同一种类型的对象的集合
  • vector 的数据结构很像数据,能非常高效和方便地访问单个元素,空间是连续的,并且可以扩展
  • vector 是一个类模板 (class template)
  • 要使用 vector 必须包含相关头文件 #include <vector> using std::vector

vector 对象初始化

  • vector 类定义了好几种构造函数
    • vector<T> v1; vector 保存类型为 T 的对象,默认构造函数 v1 为空
    • vector<T> v2(v1); v2 是 v1 的一个副本
    • vector<T> v3(n,i) v3 包含 n 个值为 i 的元素
    • vector<T> v4(n) v4 含有值初始化的元素的 n 个副本

vector 常用成员函数

成员函数功能描述
size()返回元素的个数
clear()清除所有元素
empty()判断是否为空
push_back()在末尾添加一个元素
erase()删除某个元素
insert()插入一个元素
[]返回元素
=复制副本
重载运算符[],=,>,>=,<,<=,!=,==等
  • 通过迭代器来遍历容器,迭代器可以将它看成是泛型程序指针
  • != 具有更好的可移植性,基本所有容器都有 != ,但不一定重载了< 号
  • it++ 如果后置的++运算符重载,会多了一次临时对象的创建
// ++it
//it++ 如果后置的++运算符重载,会多了一次临时对象的创建
void ShowVec(INTVEC &v)
{
// 通过迭代器来遍历容器,迭代器可以将它看成是泛型程序指针
INTVEC::iterator it;
for (it = v.begin(); it != v.end(); ++it) { // != 具有更好的可移植性,基本所有容器都有 != ,但不一定重载了< 号
cout << *it << " ";
}
cout << endl;
}
typedef vector<int> INTVEC;

//void ShowVec(const INTVEC& v)
//{
// unsigned int i;
// for (i = 0; i < v.size(); i++) {
// cout << v[i] << " ";
// }
// cout << endl;
//}

void ShowVec(INTVEC &v)
{
// 通过迭代器来遍历容器,迭代器可以将它看成是泛型程序指针
INTVEC::iterator it;
for (it = v.begin(); it != v.end(); ++it) { // != 具有更好的可移植性,基本所有容器都有 != ,但不一定重载了< 号
cout << *it << " ";
}
cout << endl;
}

void ShowVec_const(const INTVEC &v)
{ // 推荐带 const ,此时迭代器也要定义为 const_iterator
// 通过迭代器来遍历容器,迭代器可以将它看成是泛型程序指针
INTVEC::const_iterator it;
for (it = v.begin(); it != v.end(); ++it) { // != 具有更好的可移植性,基本所有容器都有 != ,但不一定重载了< 号
cout << *it << " ";
}
cout << endl;
}

void ShowVec1(INTVEC &v)
{
for (auto &item : v) // 新式的 for 循环写法
cout << item << " ";
cout << endl;
}

int main(void)
{
// vector<int> v;
INTVEC v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(5);
v.push_back(7);
ShowVec_const(v);
cout << v.back() << endl; // 并没有真正把最后一个弹出
ShowVec_const(v);
v.pop_back();
ShowVec_const(v); //此时弹出了3
// v.erase(v.begin()+3); //删掉第4个元素
v.erase(v.begin(), v.begin()+2); //移除一个范围 左闭右开
ShowVec_const(v);
v.erase(remove(v.begin(),v.end(),5),v.end()); //移除所有的元素 5 <algorithm>中的算法
ShowVec_const(v);

return 0;
}
/* 输出
1 2 3 4 5 6 5 7
7
1 2 3 4 5 6 5 7
1 2 3 4 5 6 5
3 4 5 6 5
3 4 6
*/

STL六大组件:容器、迭代器、算法、函数对象、适配器、内存分配器

c++ 新标准中的 for 循环

for (declaration: expression)
statement

注意:这里expression表示的必须是一个序列,如用花括号括起来的初始值列表({1,2,3,4})、数组([1,2,3,4])或者vector或string等类型的对象。

vector<int> a = { 1,2,3,4 };
for (int &item : a)
cout << item << endl;

vector<int> a = { 1,2,3,4 };
for (auto &item : a)
cout << item << endl;

map 介绍

map 介绍

标准库的 map 类型

  • 使用 map 需要包含 map 类所在的头文件 #include <map>,关联式容器,以 key-value 的形式存储
  • 定义一个 map 对象 map<string, int> mapTest; //string 作为索引,存储 int 对象

插入数据

  • mapTest["aaa"] = 100;
  • mapTest.insert(map<string,int>::value_type("bbb",200));
  • mapTest.insert(pair<string, int>("ddd", 400));
  • mapTest.insert(make_pair<string,int>("ccc",300));
int main(void)
{
// 插入到 map 容器内部的元素默认是按照 key 从小到大来排序
// key 类型一定要重载 < 运算符
map<string, int> mapTest;
mapTest["aaa"] = 100; // int& operator[](const string& index);
mapTest.insert(map<string,int>::value_type("bbb", 200));
// mapTest.insert(map<string,int>::value_type("bbb", 2000)); // 不允许插入
mapTest.insert(pair<string, int>("ccc", 300));
mapTest.insert(make_pair("ddd",400));
mapTest["eee"] = 500;

map<string, int>::const_iterator it;
for (it = mapTest.begin(); it != mapTest.end(); ++it) {
cout << it->first << " " << it->second << endl;
}

return 0;
}

查找与修改

  • mapTest["aaa] = 100;
  • map<string, int>::iterator it = mapTest.find(“aaa”);
  • it->second = 666;

删除

  • mapTest.erase("aaa");
  • mapTest.erase(it);