C++ STL:string(2) |Capacity|Modifiers|operations|OJ练习
上篇文章:
https://blog.csdn.net/2401_86123468/article/details/153868112?spm=1001.2014.3001.5501
1.string Capacity

1.1max_size

此时的值会根据平台而变,参考意义不大。

1.2capacity
size和capacity都不包含\0

此处capacity显示15个空间,实际上开了16个空间

1.3clear


1.4reserve

reserve在缩容时是不具有约束力的,不推荐用它扩容。

在gcc下,就会缩容,具有不确定性:

reverse的应用场景:
提前开好空间,提高效率。

1.5shrink_to_fit
此是专门用来缩容的,但一般而言,缩容代价太大(以时间换空间),不建议缩容。


1.6resize
对容量内容进行改变


2.string Modifiers

2.1push_back

string扩容的方式
第一次是二倍,之后是1.5倍的扩容。

注意:STL设计是一种规范,规定哪些容器和算法,要实现哪些接口,不同的编程平台实现是不一样的。
在g++下,为二倍扩容:

2.2append
插入单个字符用push_back,插入多个字符用append。


2.3operator+= 和 operator+
+=会修改对象本身


+不会修改对象本身,并且对字符串的拼接没有先后顺序要求,类似的还有operator比较



2.4assign
类似于赋值


2.5insert
string这里并没有提供头插头删,因为效率较低。但若是想实现头插头删,可以使用insert和erase。


2.6erase


2.7replace
效率并不高。


3.String operations
3.1find

如果没有找到,就返回npos

与replace结合,完成将空格替换为其他字符:(效率很低)

优化:

3.2rfind
支持倒着寻找字符,示例可见OJ练习章节。

4.OJ练习
4.1仅仅反转字母
https://leetcode.cn/problems/reverse-only-letters/

直接使用库里的交换

代码如下:
class Solution {bool isLetter(char ch){if(ch >= 'a' && ch <= 'z')return true;if(ch >= 'A' && ch <= 'Z')return true;return false;}
public:string reverseOnlyLetters(string s) {if(s.empty())return s;size_t begin = 0, end = s.size()-1;while(begin < end){while(begin < end && !isLetter(s[begin]))++begin;while(begin < end && !isLetter(s[end]))--end;swap(s[begin],s[end]);++begin;--end;}return s;}
};
4.2字符串中的第一个唯一字符
https://leetcode.cn/problems/first-unique-character-in-a-string/

由于题目中都是小写字母,所以将26个字母全部映射出来,再依次统计次数。
class Solution {
public:int firstUniqChar(string s) {int count[26] = {0};for(auto ch : s){count[ch - 'a']++;}for(size_t i = 0; i < s.size(); ++i){if(count[s[i] - 'a'] == 1)return i;}return -1;}
};
4.3字符串最后一个单词的长度
https://www.nowcoder.com/practice/8c949ea5f36f422594b306a2300315da?tpId=37&&tqId=21224&rp=5&ru=/activity/oj&qru=/ta/huawei/question-ranking
此题需要自己完成输入输出。

有倒着找的需求,使用rfind

#include <iostream>
#include <string>
using namespace std;int main() {string str;//cin >> str;getline(cin,str);size_t pos = str.rfind(' ');cout << str.size() - (pos + 1) << endl;
}
注意,这里的输入应当使用getline
4.4getline

一般的输入不会包含空格,并且只能以\0作为结尾。

而getline可以包含空格,并且可以指定以什么样的字符作为结尾。


4.5字符串相加
https://leetcode.cn/problems/add-strings/

class Solution {
public:string addStrings(string num1, string num2) {int end1 = num1.size() - 1, end2 = num2.size() - 1;int carry = 0;//进位string retStr;while(end1 >= 0 || end2 >= 0){int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;int ret = val1 + val2 + carry;carry = ret / 10;ret = ret % 10;//头插retStr.insert(0, 1, '0'+ret);}if(carry)retStr.insert(0, 1, '1');return retStr;}
};
由于头插每次都要挪动数据,时间复杂度为O(N^2),优化代码,尾插加逆置:
逆置:

class Solution {
public:string addStrings(string num1, string num2) {int end1 = num1.size() - 1, end2 = num2.size() - 1;int carry = 0;//进位string retStr;retStr.reserve(max(num1.size(), num2.size())+1);while(end1 >= 0 || end2 >= 0){int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;int ret = val1 + val2 + carry;carry = ret / 10;ret = ret % 10;//头插//retStr.insert(0, 1, '0'+ret);retStr += ('0' + ret);}if(carry)//retStr.insert(0, 1, '1');retStr += '1';reverse(retStr.begin(), retStr.end());return retStr;}
};
本章完。
