【C++】C++ STL 探索:String的使用与理解(一)https://developer.aliyun.com/article/1617331
四、string类对象的访问
关于string类对象的访问,关键掌握operator[]就行。剩下三个不如operator[]好用,其中front、back是为了规范性才实现的。
4.1 operator[]
int main() { string str1("hello world"); for (int i=0;i<str1.size();i++) { //cout << str1.operator[](i) << endl; cout << str1[i] << endl; } const string str2("hello world"); for (int i = 0; i < str2.size(); i++) { //str2[i]++; const修饰的话,没有修改的权限 cout << str2[i] << endl; } return 0; }
五、string类对象的遍历操作
函数名称 | 功能说明 |
operator[] (重 点) | 返回pos位置的字符,const string类对象调用 |
begin+ end | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器 |
rbegin + rend | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器 |
范围for | C++11支持更简洁的范围for的新遍历方式 |
string类对象三种遍历方式:
- for+[]
- 范围for(本质还是迭代器)
- 迭代器(begin(),end())
这个三种遍历方式不仅可以遍历string对象,还能遍历修改string中的字符
注意:在string遍历时使用最多的是for+下标方括号[]或者范围for(C++11后才支持)。begin()+end()大多数使用在需要使用STL提供的算法操作string时,比如:采用reverse逆置string。
第一种:for+下标方括号[]
int main() { string str1("hello world"); int sz = str1.size(); for (int i = 0; i < sz; i++) { //cout<<str1.operator[](i)<<endl; cout << str1[i] << endl; } return 0; }
第二种:范围for
int main() { string str1("hello world"); int sz = str1.size(); for (auto ch : str1)//从str1读取字符给变量ch,auto会自动识别类型 { cout << ch << endl; } return 0; }
接下来单独介绍下迭代器
六、迭代器(简单介绍)
6.1 迭代器概念
迭代器(Iterator)是一种用于遍历容器(如列表、字典、集合等)元素的对象。它提供了一种统一的访问容器内部元素的方式,而不必暴露容器的具体实现细节。迭代器通常用于循环结构中,让程序员能够逐个访问容器中的元素。
int main() { string str1("hello world"); string::iterator it = str1.begin(); while (it != str1.end()) { cout << *it << endl; it++; } return 0; }
虽然推荐使用上面两种方式,但是迭代器才是主流。对于链表、树等数据结构,迭代器不在乎底层实现,是通用的遍历容器。迭代器是一种像指针的东西,他可以是指针也可以不是指针,具体还是看不同编译器的底层实现,迭代器有两种类型分别:可读可修改,可读不可修改
在string中定义迭代器:
string::iterator it = str1.begin();
string::iterator it = str1.end();
简单说明:
begin()返回指向第一个位置的迭代器或指针,可以用于访问第一个位置元素,而end()返回指向最后一个位置之后的迭代器,它指向的是标记字符串的结尾。
可以使用容器类型的迭代器类型来声明变量:std::vector
容器,begin()和end()
返回的是str::vector::iterator
类型的迭代器,可以将其存储相应的变量中。
总之,存储迭代器的变量类型应该与容器的迭代器类型相匹配,以确保类型的一致性,避免编译器报错或者意外行为
6.2 反向迭代器(reverse_iterator)
反向迭代器定义:string::reverse_iterator
int main() { string str1("hello world"); string::reverse_iterator rit = str1.rbegin(); while (rit != str1.rend()) { cout << *rit << ""; ++rit; } cout << endl; return 0; }
说明:rbegin()返回逆向迭代器位置,由于本来就是倒置的,++就是向前遍历。实际上很少使用场景,正向迭代器也可以满足倒着遍历的需求。
七、Modifiers(string类对象的修改操作)
函数名称 | 功能说明 |
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一个字符串 |
operator+= (重点) | 在字符串后追加字符串str |
c_str(重点) | 返回C格式字符串 |
find + npos(重点) | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好,减少扩容次数,提高性能
7.1 push_back
int main() { string str1;//定义一个string类对象 for (int i = 0; i < 10; i++) { str1.push_back('c'); } cout << str1 << endl; return 0; }
功能:将一个字符尾插到字符串中
疑问:push_back也不常用,既然支持一个字符尾插,为什么不顺便支持字符串。需要实现个支持字符串的接口,两个接口放在一起显得冗余
7.2 append
int main() { string str1; str1.append("hello world"); cout << str1 << endl; return 0; }
功能:在字符串后追加一个字符串
对于append有很多个函数重载,这里只需要记住经常使用的就行了,其他了解下即可,但是无论是push_back,还是append,我们都不喜欢使用的,比较喜欢使用operator+=
7.3 operator+=(重要)
int main() { string str1,str2; str1 += 'c'; cout << str1 << endl; str2 += "hello world"; cout << str2 << endl; str2 += str1; cout << str2 << endl;//输出结果:hello worldc return 0; }
注意:虽然str1.push_back('c')、str1.append(1,'c')、str1+='c'
三种的实现逻辑差不多,但是一般情况string类使用operator+=操作比较多,在于+=操作不仅可以连接单个字符,还可以连接字符串
7.4 assign
int main() { string str1("hello world"); str1.assign("xxx"); cout << str1 << endl;//xxx return 0; }
功能:将空间中数据清空再添加所需内容,就是赋值的意思。如果出现空间不足问题,会自动扩容满足当前空间需求。
7.5 insert
int main() { string str1("hello world"); str1.insert(2, "xxx"); cout << str1 << endl;//hexxxllo world return 0; }
功能:从某个位置开始插入字符
7.6 erase
int main() { string str1("hello world"); str1.erase(0, 3); cout << str1 << endl; str1.erase(); cout << str1 << endl; return 0; }
功能:从某个位置开始删除len个字符。如果需删除字符超过size,则有多少删多少
如果没有给具体需要删除几个字符,采用缺省值npos,默认全部删除。留下一行空格表示,当前空间没有释放。
7.7 replace
int main() { string str1("hello world"); str1.replace(5, 1, "%"); cout << str1 << endl;//hello%world return 0; }
功能:在字符串中某个区间位置的字符进行字符替换
小结:对于insert、erase、replace来说,底层逻辑是挪动数据,时间复杂度很高,效率很低,能不使用就不使用,建议多使用operator+=。
7.8 find
返回值:如果找到相对应的字符后,find会返回该字符所在的索引位置(从0开始的下标索引位置),如果没有匹配成功,find则会返回npos(-1);
7.8.1 size_t find(const char* s, size t pos = 0) const
size_t find(const char* s, size t pos = 0) const; int main() { string str1("file.cpp"); size_t pos = str1.find('.'); cout << pos << endl; return 0; }
功能:find从pos开始位置,查找字符串中所需字符所在位置
7.8.2 size t find(char c,size t pos =0) const
int main() { string str1("https://cplusplus.com/reference/string/string/find/"); size_t pos = str1.find("://", 2); cout << pos << endl; return 0; }
功能:find从pos开始位置,查找字符串中所需字符串位置,并返回开头字符的下标
【C++】C++ STL 探索:String的使用与理解(三)https://developer.aliyun.com/article/1617333