1.基本定义和用途
- string是一个专门用于处理字符串的类,它是basic_string模板的一个特化。
- 主要用于存储和操作文本数据。
- 底层实现通常是一个字符数组,并且具有字符串特定的操作,如连接、查找、子串等。
2.底层实现
string
在大多数实现中是一个动态数组,通常包括一个指向字符数组的指针、长度(size
)和容量(capacity
)。语义上表示一个不可分割的文本序列。- string通常采用小字符串优化(Small String Optimization, SSO),对于短字符串,直接存储在栈上,避免堆分配。
- string主要用于存储char类型,其他容器可以存储任意类型的对象。
- string内部管理一个以空字符('\0')结尾的字符数组,与C语言中的C风格字符串(
char*
)具有很好的兼容性,通过c_str()
方法可以轻松获取C风格字符串,这些使得它可以方便地与C风格字符串互操作。
3.特定操作的支持
- sting专门针对字符串进行了优化,提供了许多字符串特有的操作,比如
append
,substr
,find
,compare
,replace
等。 - C++标准库提供了一些专门用于字符串处理的非成员函数算法,如std::stoi, std::to_string等。
append
std::string str = "Hello";
str.append(" World"); // 结果为 "Hello World"
str.append(3, '!'); // 结果为 "Hello World!!!"
substr
std::string str = "Hello, World!";
std::string sub = str.substr(7, 5); // 结果为 "World"
std::string sub2 = str.substr(7); // 结果为 "World!"
find
std::string str = "Hello, World!";
size_t pos = str.find("World"); // 结果为 7
size_t pos2 = str.find('o'); // 结果为 4
size_t pos3 = str.find("Earth"); // 结果为 std::string::npos
compare
std::string str1 = "Hello";
std::string str2 = "World";
int result = str1.compare(str2); // 结果为负数,因为 "Hello" 小于 "World"
int result2 = str1.compare("Hello"); // 结果为 0,因为两个字符串相等
replace
std::string str = "Hello, World!";
str.replace(7, 5, "Universe"); // 结果为 "Hello, Universe!"
str.replace(0, 5, 3, '*'); // 结果为 "***o, Universe!"
4.函数中的使用差异
在 C++ 的 std::string
类中,有一些算法函数既支持使用字符串的索引(通过下标)或完整的字符串对象,又支持使用迭代器来进行操作。这些函数可以处理字符串的特定范围或字符序列,提供了灵活的操作方式。以下是支持这两种操作方式的函数:
1. replace
-
支持下标和迭代器:
- 通过下标:可以使用起始位置
pos
和长度len
来替换字符串的子串。 - 通过迭代器:可以指定要替换的范围的起始和结束迭代器。
std::string str = "Hello, World!"; // 使用下标 str.replace(7, 5, "Universe"); // 结果为 "Hello, Universe!" // 使用迭代器 auto it1 = str.begin() + 7; auto it2 = str.begin() + 14; str.replace(it1, it2, "Everyone"); // 结果为 "Hello, Everyone!"
- 通过下标:可以使用起始位置
2. insert
-
支持下标和迭代器:
- 通过下标:可以使用索引
pos
在指定位置插入字符串或字符。 - 通过迭代器:可以使用迭代器在指定位置插入字符串或字符。
- 通过下标:可以使用索引
std::string str = "Hello, World!";
// 使用下标
str.insert(7, "Beautiful "); // 结果为 "Hello, Beautiful World!"
// 使用迭代器
auto it = str.begin() + 7;
str.insert(it, 'X'); // 结果为 "Hello, XBeautiful World!"
3. erase
-
支持下标和迭代器:
- 通过下标:可以使用起始位置
pos
和长度len
删除字符串中的一部分。 - 通过迭代器:可以使用迭代器指定要删除的字符或范围。
- 通过下标:可以使用起始位置
std::string str = "Hello, Beautiful World!";
// 使用下标
str.erase(7, 10); // 结果为 "Hello, World!"
// 使用迭代器
auto it1 = str.begin() + 7;
auto it2 = str.begin() + 12;
str.erase(it1, it2); // 结果为 "Hello, ld!"
4. find
-
支持下标和迭代器:
- 通过下标:虽然
find
函数主要是基于索引查找子串或字符,但结果可以转换为迭代器形式。 - 通过迭代器:虽然
find
本身不直接接受迭代器作为参数,但可以使用下标结果来获取相应的迭代器。
- 通过下标:虽然
std::string str = "Hello, World!";
// 使用下标查找
size_t pos = str.find("World"); // 结果为 7
// 将结果转换为迭代器
if (pos != std::string::npos) {
auto it = str.begin() + pos;
std::cout << *it; // 输出 'W'
}
5. substr
-
支持下标和迭代器:
- 通过下标:可以指定起始位置和长度来提取子串。
- 通过迭代器:虽然
substr
本身不直接接受迭代器,但可以通过迭代器转换为索引来提取子串。
std::string str = "Hello, World!";
// 使用下标提取子串
std::string sub = str.substr(7, 5); // 结果为 "World"
// 使用迭代器
auto it1 = str.begin() + 7;
auto it2 = str.begin() + 12;
std::string sub2(it1, it2); // 结果为 "World"
6.小结
以下是 std::string
支持通过下标和迭代器操作的主要函数:
replace
:支持使用下标和迭代器替换字符串的部分内容。insert
:支持在指定位置(下标或迭代器)插入字符串或字符。erase
:支持通过下标和迭代器删除字符串的部分内容。find
:尽管主要基于下标操作,但查找到的位置可以转换为迭代器使用。substr
:主要基于下标操作,但可以通过迭代器转换来提取子串。
这些函数提供了丰富的字符串操作方式,在处理字符串时能够根据具体需求选择更合适的操作方式。
5.总结
string
和其他STL容器在算法函数上的区别主要体现在专有方法的可用性、效率优化和语义上。std::string
提供了大量专门处理字符串的函数,这使得它在处理字符串时比其他STL容器更加高效和方便,而其他STL容器则更通用,适用于处理各种类型的数据并与标准算法库无缝集成。在实际开发中,选择使用std::string
的专有方法或标准算法需要根据具体的应用场景来决定。string
提供了下标和迭代器两种访问方式,各有优缺点。下标适合简洁、高效的随机访问,迭代器则适合灵活、复杂的遍历操作。对于简单的字符访问,下标是首选;对于需要复杂操作或与标准算法结合使用的场景,迭代器则更为合适。