STL的基本概念
为了建立数据结构和算法的一套标准,提高复用性,诞生了STL(Standard Template Library标准模板库)。
STL里面基本全部都是采用了模板类或者模板函数。
STL从广义上分为三大部分:容器(container)、算法(algorithm)迭代器(iterator)
容器和算法之间通过迭代器来进行连接,比如:容器存储学生的信息,算法来对操作进行排序求平均值,迭代器来获取容器中学生的信息。
容器:存放内容,存储数据,STL容器是通过数据结构来进行数据存储的。
算法:解决问题,比如求和,求平均值等。
迭代器:本质上就是指针,依次指向容器中的每一个元素,可以访问容器中的元素。
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
算法:各种常用的算法,如sort、find、copy、for_each等。
迭代器:扮演了容器与算法之间的胶合剂。
仿函数:行为类似函数,可作为算法的某种策略。
适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
空间配置器:负责空间的配置与管理。
String容器
string本质上一个类,是一个特殊的STL容器,元素只能是char类型。
String和char *的区别
char * 是一个指针,但是string是一个类,里面封装了char *;
string管理char *所分配的内容,不用担心复制的越界和取值的越界问题等,由类的内部来进行处理。
string内部封装很多成员方法,比char *更加灵活
String的构造函数
构造函数原型:
string(); // 创建一个空的字符串,比如string str;
string(const char* s); //使用字符串s初始化;
string(const string& str); //使用一个string对象初始化另一个string对象;
string(int n, char c); //使用n个字符c初始化;
void test01()
{
// 无参构造,创建一个空的字符串
string s1;
cout << "s1 = " << s1 << endl;
const char* str = "hello world";
string s2(str); // 将字符串常量str转化为了string类型
cout << "s2 = " << s2 << endl;
// 利用拷贝构造函数 来初始化s3
string s3(s2);
cout << "s3 = " << s3 << endl;
string s4(10, 'w'); // 用10个w来初始化s4字符串
cout << "s4 = " << s4 << endl;
}
String的赋值操作
功能描述: 给string字符串进行赋值;
赋值的函数原型:
重载赋值运算符:
string& operator=(const char* s); //char*类型字符串 赋值给当前的字符串;
string& operator=(const string &s); //把字符串s赋给当前的字符串;
string& operator=(char c); //字符赋值给当前的字符串;
赋值函数assign():
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赋给当前字符串;
void test02()
{
// 使用重载运算符来实现赋值
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;
// 使用赋值assign()来实现
string str4;
str4.assign("hello C++");
cout << "str4 = " << str4 << endl;
string str5;
str5.assign("program", 3);
cout << "str5 = " << str5 << endl;
string str6;
str6.assign(str5);
cout << "str6 = " << str6 << endl;
string str7;
str7.assign(5, 'x');
cout << "str7 = " << str7 << endl;
}
String 字符串的拼接
功能描述: 实现在字符串末尾拼接字符串
函数原型:
重载+=运算符:
string& operator+=(const char *s); //字符串常量拼接;
string& operator+=(const string& s); //用string类型的字符串进行拼接;
string& operator+=(const char c); //单个字符拼接;
append函数
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); // pos是position位置,代表从0开始的下标,从pos位置开始,将s字符串后面的n个字符拼接到当前的字符串后面;
void test03()
{
// 字符串拼接
// 重载+=运算符实现
string str1 = "我";
str1 += "今天要中500万";
cout << "str1 = " << str1 << endl;
str1 += ':';
cout << "str1 = " << str1 << endl;
string str2 = "白日的梦";
str1 += str2;
cout << "str1 = " << str1 << endl;
// 使用append方法来实现拼接
string str3 = "I";
str3.append(" like ");
str3.append("play game such as", 10);
string str4 = "LOL DNF";
str3.append(str4, 4, 3);
cout << "str3 = " << str3 << endl;
}
String查找和替换
功能描述:
查找:查找指定的字符串是否存在,如果存在返回对应位置,找不到返回-1;
替换:在指定的位置替换字符串;
函数原型:
注意:查找函数是常成员函数;
从左往右:find
int find(const string& str, int pos=0) const; // 查找字符串str,返回第一次出现的位置,从pos开始查找。pos默认值为0,也就是从字符串的最开始的位置来查;
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第一次出现的位置;
从右往左:rfind
int rfind(const string& str, int pos=npos) const; // 从右往左查找str最后一次出现的位置,从pos位置开始查找,pos默认值是npos,npos是string类的静态常量,值是-1,表示字符串结束;
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最后一次出现的位置;
替换函数原型
replace:
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 test04()
{
// 从左往右找
string str1 = "abcdefgde";
int pos = str1.find("de");
cout << "第一个出现de字符串的位置是:" << pos << endl;
pos = str1.find("de", 5);
cout << "第二个出现de字符串的位置是:" << pos << endl;
pos = str1.find("fgde", 0, 2);
cout << "fg字符串出现的位置是:" << pos << endl;
pos = str1.find('g');
cout << "g字符出现的位置是:" << pos << endl;
//从右往左找
cout << "从右往左找" << endl;
// 因为de是一个整体字符串,找到后一字符串的第一个字符在所查找的字符串中的位置为准来返回结果
pos = str1.rfind("de");
cout << "第一个出现de字符串的位置是: " << pos << endl;
pos = str1.rfind("de",5);
cout << "第二个出现de字符串的位置是:" << pos << endl;
// 从pos位置开始查找字符串中的前n个字符出现的位置
pos = str1.rfind("fgde", 6, 2);
cout << "fg出现的位置是:" << pos << endl;
pos = str1.rfind('e');
cout << "e出现的位置是:" << pos << endl;
// 替换
str1.replace(1, 4, "8888");
cout << "被替换后的结果为:str1 = " << str1 << endl;
}
String字符串的比较
比较方式
按照字符对应的ASCII码值来进行比较, 从头开始依次比较,直到遇到了第一个ASCII值不同的字符,来比较字符的大小。
字符串对比主要是用于比较两个字符串是否相等,判断谁大谁小的意义并不是很大。
返回 0 字符串相等。
返回 1 前面的字符串大于后面的。
返回-1 前面的字符串小于后面的
函数原型
int compare(const string &s) const; //与字符串s比较
int compare(const char *s) const; //与字符串s比较
void test01()
{
string s1 = "hello";
string s2 = "hello";
string s3 = "Hello";
int res1 = s1.compare(s2);
int res2 = s1.compare(s3);
if (res1 == 0)
{
cout << "s1和s2是相等的" << endl;
}
else
{
cout << "s1和s2是不相等的" << endl;
}
if (res2 == 0)
{
cout << "s1和s3是相等的" << endl;
}
else if (res2 == 1)
{
cout << "s1大于s3" << endl;
}
else
{
cout << "s1小于s3" << endl;
}
}
String的插入和删除
功能描述:对string字符串进行插入和删除字符操作。
函数原型:
插入:
string& insert(int pos, const char *s); // 从pos位置插入字符串
string& insert(int pos, const string&s); // 从pos位置插入字符串
string& insert(int pos, int n, char c); //在指定位置插入n个字符c
删除:
string& erase(int pos, int n = npos); // 删除从pos开始的n个字符
void test02()
{
// 插入
string str = "helloWorld";
str.insert(1, "888");
cout << "str = " << str << endl;
str.insert(1, 3, 'a');
cout << "str = " << str << endl;
// 删除
str.erase(2,3); // 从下标索引2开始删除3个字符
cout << "str = " << str << endl;
}
String截取字符串
功能描述:从字符串中获取想要的子串
函数原型:
string substr(int pos = 0, int n = npos) const; //返回有pos开始的n字符组成字符串,n默认值是npos,npos代表结束位置的下标,即整个字符串的长度。
void test03()
{
string str = "abcdef";
string subStr1 = str.substr(1, 4);
cout << "substr1 = " << subStr1 << endl;
string subStr2 = str.substr(3); // 如果只写一个数字,代表从指定的下标开始一直截取到字符串的最后位置
cout << "substr2 = " << subStr2 << endl;
// 可以直接获取string类型字符串的长度
cout << "str的长度是:" << str.size() << endl;
}
String获取长度和字符存取
size() 可以直接获取字符串的长度
char& operator[](int n) ; // 运算符重载,通过[]下标来获取字符
char& at(int n); // 通过at方法来获取字符
// 字符的存取
void test04()
{
// 取
string str = "helloWorld";
cout << str[4] << endl;
for (int i = 0; i < str.size(); i++)
{
cout << str[i] << " ";
}
cout << endl;
cout << str.at(5) << endl;
// 存,直接利用下标来改变字符
str[0] = 'H';
str.at(5) = 'w';
cout << str << endl;
}
字符串的常用操作
// string字符串的常用操作
// 1、string和char *的转换
void test05()
{
// char* 转字符串,利用拷贝构造函数
const char* s1 = "welcome to china";
string s2 = string(s1);
cout << "s2 = " << s2 << endl;
string s3 = "hello";
char* s = &s3[0];
cout << "s = " << s << endl;
//利用标准库中的c_str()方法,将string类型的字符串转化为c风格的字符串即 char *
string s4 = "let begin";
const char* c = s4.c_str();
cout << c << endl;
}
// 2、对一个邮箱地址进行处理,获取邮箱的用户名,比如hello@sina.com,获取出来的结果是hello
string getEmailName(string& s)
{
int pos = s.find('@');
string username = s.substr(0, pos);
return username;
}
//3、对一个字符串中的字符进行大小写转换(字符串都是英文字符)
// 思路:对比字符的ASCII码即可,大小写相差32
string upperAndLower(string& str)
{
for (int i = 0; i < str.size(); i++)
{
if (str[i] >= 65 and str[i] <= 90) // 如果是大写字母,就加32转化为小写字母
{
str[i] += 32;
}
else // 负责就是小写字母,减32转化为大写字母
{
str[i] -= 32;
}
}
return str;
}
//4、 判断一个字符串中的内容是否都是数字
bool isNum(string str)
{
for (int i = 0; i < str.size(); i++)
{
int temp = (int)str[i]; // int类型转化后可以获取到字符对应ASCII码值
// 不用转化 在比较的也能进行隐式转换成ASCII码进行比较
if (temp >= 48 && temp <= 57)
{
continue;
}
else
{
return false;
}
}
}
// 5、验证.com类邮箱的有效性,是否在中间包含@字符并且以.com结尾
bool verifyEmail(string s)
{
int index = s.find('@');
if (index == -1 || index == 0) // 必须先找到@字符,并且不能在第一个位置
{
return false;
}
index = s.find(".com");
if (index == -1 || index != (s.size() - 4)) // 必须要找到.com字符串并且必须在最后四个字符的位置出现
{
return false;
}
return true; // 如果两种情况都没发生,就直接返回true
}
int main()
{
//string str1 = "abcDE";
cout << upperAndLower(str1) << endl;
//for (int i = 0; i < str1.size(); i++)
//{
// //str1[i] = tolower(str1[i]);
// str1[i] = toupper(str1[i]);
//}
//cout << str1 << endl;
//string str1 = "a1999";
//if (isNum(str1))
//{
// cout << str1 << "都是数字" << endl;
//}
//else
//{
// cout << str1 << "有非数字" << endl;
//}
string str = "dijia@qq.com";
cout << verifyEmail(str) << endl;
return 0;
}