目录
容器的分类
string
string的概念
string的初始化
string的遍历
string的一些基本操作
char*类型和string类型互转
字符串的连接
字符串的查找和替换
string的截断和删除
容器的分类
在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在 细节上有所出入。STL容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模板,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化。
容器部分主要由头文 件<vector>,<list>,<deque>,<set>,<map>,<stack> 和<queue>组成。
序列式容器(Sequence containers)
每个元素都有固定位置--取决于插入时机和地点,和元素值无关。
vector、deque、list
关联式容器(Associated containers)
元素位置取决于特定的排序准则,和插入顺序无关
set、multiset、map、multimap
数据结构 | 描述 | 实现头文件 |
向量(vector) | 连续存储的元素 | <vector> |
列表(list) | 由节点组成的双向链表,每个结点包含着一个元素 | <list> |
双队列(deque) | 连续存储的指向不同元素的指针所组成的数组 | <deque> |
集合(set) | 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 | <set> |
多重集合(multiset) | 允许存在两个次序相等的元素的集合 | <set> |
栈(stack) | 后进先出的值的排列 | <stack> |
队列(queue) | 先进先出的执的排列 | <queue> |
优先队列(priority_queue) | 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 | <queue> |
映射(map) | 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 | <map> |
多重映射(multimap) | 允许键对有相等的次序的映射 | <map> |
string
string的概念
- string是STL的字符串类型,通常用来表示字符串。而在使用string之前,字符串通常是用char*表示的。string与char*都可以用来表示字符串,那么二者有什么区别呢。
string和char*的比较
- string是一个类, char*是一个指向字符的指针。
string封装了char*,管理这个字符串,是一个char*型的容器。
- string不用考虑内存释放和越界。
string管理char*所分配的内存。每一次string的复制,取值都由string类负责维护,不用担心复制越界和取值越界等。
- string提供了一系列的字符串操作函数
查找find,拷贝copy,删除erase,替换replace,插入insert
string的初始化
string主要有四种初始化的方式。
- 默认构造函数:
string(); //构造一个空的字符串string s1。
- 拷贝构造函数:
string(const string &str); //构造一个与str一样的string。如string s1(s2)。
- 带参数的构造函数
string(const char *s); //用字符串s初始化
string(int n,char c); //用n个字符c初始化
void main21()
{
string s1 = "aaaa";
string s2("bbbb");
string s3 = s2;//通过拷贝构造函数来初始化对象
string s4(10, 'a');
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
cout << "s3:" << s3 << endl;
cout << "s4:" << s4 << endl;
}
string的遍历
string主要有两种方式,一种是通过数组的方式进行遍历,另外一种是通过迭代器的方式进行遍历,数组方式出现错误的时候不会向外抛出异常,而迭代器会。
//string的遍历
void main22()
{
string s1 = "abcdefg";
//1 数组方式
for (int i = 0; i < s1.length(); i++)
{
cout << s1[i] << " ";//出现错误不向外面抛出异常引起程序的中断
}
cout << endl;
//2 迭代器
for (string::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
try
{
for (int i = 0; i < s1.length()+3; i++)
{
cout << s1.at(i) << " ";//抛出异常
}
}
catch (...)
{
cout << "发生异常\n";
}
cout << endl;
}
string的一些基本操作
char*类型和string类型互转
const char *c_str() const; //返回一个以'\0'结尾的字符串的首地址.
//字符指针和string的转换
void main23()
{
string s1 = "aaabbb";
//1 s1===>char *
printf("s1:%s\n", s1.c_str());
//2 char *===>string
//3 s1的内容copy buf中
char buf[128] = { 0 };
s1.copy(buf, 3, 0);//注意 只给你copy3个字符 不会加\0
cout << "buf1:" << buf << endl;
}
字符串的连接
string &operator+=(const string &s); //把字符串s连接到当前字符串结尾
string &operator+=(const char *s);//把字符串s连接到当前字符串结尾
string &append(const char *s); //把字符串s连接到当前字符串结尾
string &append(const char *s,int n); //把字符串s的前n个字符连接到当前字符串结尾
string &append(const string &s); //同operator+=()
string &append(const string &s,int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
string &append(int n, char c); //在当前字符串结尾添加n个字符c
//字符串的连接
void main24()
{
string s1 = "aaa";
string s2 = "bbb";
s1 = s1 + s2;
cout << s1 << endl;
string s3 = "333";
string s4 = "444";
s3.append(s4);
cout << s3 << endl;
}
字符串的查找和替换
查找
int find(char c,int pos=0) const; //从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos=0) const; //从pos开始查找字符串s在当前字符串的位置
int find(const string &s, int pos=0) const; //从pos开始查找字符串s在当前字符串中的位置
find函数如果查找不到,就返回-1
int rfind(char c, int pos=npos) const; //从pos开始从后向前查找字符c在当前字符串中的位置
int rfind(const char *s, int pos=npos) const;
int rfind(const string &s, int pos=npos) const;
//rfind是反向查找的意思,如果查找不到, 返回-1
替换
string &replace(int pos, int n, const char *s);//删除从pos开始的n个字符,然后在pos处插入串s
string &replace(int pos, int n, const string &s); //删除从pos开始的n个字符,然后在pos处插入串s
void swap(string &s2); //交换当前字符串与s2的值
//字符串的查找和替换
void main25()
{
string s1 = "wbm hello wbm 111 wbm 222 wbm 333";
//查找第一次wbm index
int index = s1.find("wbm", 0);//位置下标从0开始
cout << "index:" << index << endl;
//求wbm出现的次数 每一次出现的数组下标
int offindex = s1.find("wbm", 0);
while (offindex!=string::npos)
{
cout << "offindex:" << offindex << endl;
offindex = offindex + 1;
offindex = s1.find("wbm", offindex);
}
//替换 把小写换成大写
string s3 = "aaa bbb ccc";
s3.replace(0, 3, "AAA");
cout << "s3:" << s3 << endl;
offindex = s1.find("wbm", 0);
while (offindex != string::npos)
{
cout << "offindex:" << offindex << endl;
s1.replace(offindex, 3, "WBM");
offindex = offindex + 1;
offindex = s1.find("wbm", offindex);
}
cout << "s1:" << s1 << endl;
}
string的截断和删除
string &insert(int pos, const char *s);
string &insert(int pos, const string &s);
//前两个函数在pos位置插入字符串s
string &insert(int pos, int n, char c); //在pos位置 插入n个字符c
string &erase(int pos=0, int n=npos); //删除pos开始的n个字符,返回修改后的字符串
//截断和删除
void main26()
{
string s1 = "hello1 hello2 hello1";
string::iterator it = find(s1.begin(), s1.end(), 'l');
while (it != s1.end())
{
s1.erase(it);
it = find(it, s1.end(), 'l');
}
cout << "s1:" << s1 << endl;
s1.erase(s1.begin(), s1.end());
cout << "s1:" << s1 << endl;
cout << "s1.length():" << s1.length() << endl;
string s2 = "BBB";
s2.insert(0, "AAA"); // 头插法
cout << "s2:" << s2 << endl;
s2.insert(s2.length(), "CCC");
cout << "s2:" << s2 << endl;
}
string算法相关
将字符串的大小写互相转换的函数
void main27()
{
string s1 = "AAAbbb";
//函数的入口地址 函数对象 预定义的函数
transform(s1.begin(), s1.end(), s1.begin(), toupper);
cout << s1 << endl;
string s2 = "AAAbbb";
transform(s2.begin(), s2.end(), s2.begin(), tolower);
cout << s2 << endl;
}