C++ STL标准库 《string原理与实战分析》

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
实时计算 Flink 版,5000CU*H 3个月
简介: C++ STL标准库 《string原理与实战分析》

一、string原理

std::string 是 STL 中的一个容器类,用于处理字符串数据。以下是 std::string 的一些基本原理:

  1. 动态数组std::string 内部通常使用动态数组(如 char 数组)来存储字符。这意味着 std::string 可以根据需要自动调整大小。
  2. 短字符串优化(SSO):为了提高小字符串的性能,std::string 实现了短字符串优化。这意味着对于短字符串,std::string 可能不会使用动态分配的内存,而是在对象的内部存储空间中直接存储字符。
  3. 内存管理std::string 负责管理其内部字符数组的内存。当字符串增长时,std::string 会进行内存重新分配,并复制旧字符到新分配的内存中。
  4. 迭代器std::string 支持迭代器,允许用户使用迭代器遍历字符串中的字符。
  5. 容量和大小std::string 提供了 .size() 方法来获取字符串的长度,以及 .capacity() 方法来获取当前分配的内存大小。
  6. 构造函数和析构函数std::string 有多种构造函数,允许从不同的数据源创建字符串,如 C 风格的字符数组、另一个 std::string 对象、字符等。析构函数负责释放 std::string 占用的内存。
  7. 成员函数std::string 提供了丰富的成员函数,如 append()insert()erase()find() 等,用于操作字符串。
  8. C++11 特性:从 C++11 开始,std::string 支持移动语义,这意味着在某些情况下,std::string 对象可以高效地在函数间传递,而不需要复制整个字符串。
  9. 异常安全std::string 的操作通常是异常安全的,这意味着即使在操作过程中发生异常,std::string 对象也会保持在有效状态。
  10. 本地化std::string 支持本地化功能,可以与本地化相关的函数(如 std::collate)一起使用,以支持多语言环境。


二、string实战操作分析

1、输入

string s;

cin >> s; 
getline(cin, s) ;       //使用默认的'\n'作为终止符
getline(cin, s, '!') ;    //以'!'作为终止符

2、复制

string s1 = "hello World" ;
string s2 = s1 ;        //"hello World"     复制,
string s3(s1);      //"hello World"      拷贝构造函数, 
string s4(s1, 2);    //"llo World"     将s1的第2个位置到末尾当作字符串的初值 
string s5(s1, 3, 5);    //"lo Wo"      将s1的第2个位置开始的5个字符作为字符串的初值 
string s8(5, 'a');   //“aaaaa”     生成一个字符串,包含5个c字符

3、连接

string s1 = "Hello" ;
string s2 = "World" ;string s3, s4;
s1 += s2 ;          //"HelloWorld"    连接  
s3 = string("aaa") + "bbb";    //"aaabbb" 
s4 = "aaa" + "bbb";    //错误, 必须转成string类型!!!!!

4、比较

string s1 = "hello" ;
string s2 = "world" ;
if(s1 < s2)
cout<<"s1 < s2" ;    //比较

5、倒置串

string s = "hello" ;
reverse(s.begin(), s.end()) ;        //需要包含algorithm头文件, #include<algorithm> 

6、查找串

string s1 = "hhhelloworlddd" ;   //位置从0 ~ 9 
s1.find("w") ;    // 7    找第1个w的位置 
s1.find("w", 10) ;    // -1     从第10个位置开始找w  

s1.find_first_of("o");   //6     找第1次出现"o"的位置 
s1.find_first_of("o",7);  //8    从s1的第7个位置开始查找 
s1.find_first_not_of("h");  //3    找第1个不是"h"的字符的位置 

s1.find_last_of("o");  //8     //从后面开始找"o" 
s1.find_last_of("o", 7);  //6   //从后面7个字符中找"o"出现的位置 
s1.find_last_not_of("d");  //10

7、替换和字串

string s1,s2,s3; 
s1 = "hello world!" ;   
s2 = s1.substr(3, 5);  //"lo wo"    从第3个位置开始,往后5个字符 
s3 = s1.substr(6);    //"world!"    从第6个字符到末尾部分 
s1.replace(2, 5, "tt");  //"hettorld"    从第2个位置,往后5个字符换成“tt”

8、修改字符串

①. append - 追加
 string s = "hello" ;
 s.append("world") ;        //将"world"追加到s中
    
②. push_back - 追加字符到字符串
 string s = "hello" ;
 s.push_back('!') ;        //将'!'追加字符到字符串s中
    
③. insert - 插入
 string s = "hello" ;
 s.insert(2, "www") ;    //将字符串"www"插入到字符串s中, 插入位置为2
            
④. erase - 从字符串中擦除一些字符
 string s = "hello" ;
 s.erase(1, 2) ;            //从下标为1处向后擦去2个字符
            
⑤. swap - 与另一字符串交换内容
 string s1 = "hello" ;
 string s2 = "world" ;
 s1.swap(s2) ;            //将s1与s2中的字符串进行交换

9、获取字符串状态

 s.size()                //返回字符串大小
 s.length()              //返回字符串长度
 s.max_size()            //返回字符串最大长度
 s.clear()               //清空字符串
 s.empty()               //判断字符串是否为空


10、string中的所有s1都替换成s2

#include <iostream>
#include <string>

using namespace std;

//"12212"这个字符串的所有"12"都替换成"21"
string& replace_all(string str, const string& old_value, const string& new_value)  //替换为22211
{
    while (true)
    {
        string::size_type pos(0);
        if ((pos = str.find(old_value)) != string::npos)
        {
            str.replace(pos, old_value.length(), new_value);
        }
        else
        {
            break;
        }
    }
    return str;
}

string& replace_all_distinct(string str, const string& old_value, const string& new_value) //替换为21221
{
    for (string::size_type pos(0); pos != string::npos; pos += new_value.length())
    {
        if ((pos = str.find(old_value, pos)) != string::npos)
        {
            str.replace(pos, old_value.length(), new_value);
        }
        else
        {
            break;
        }
    }
    return str;
}

int main()
{
    cout << replace_all(string("12212"), "12", "21") << endl;   //22211
    cout << replace_all_distinct(string("12212"), "12", "21") << endl;   //21221

    return 0;
}


相关文章
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
118 2
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
232 73
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
171 3
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
219 1
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
37 0
|
4月前
|
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
117 11
|
4月前
|
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
113 9
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
244 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问