电商网站可以用dw做,手机网站 程序,企业官网网页设计报价,找文网优化的技术团队相信大家都知道STL在C中的重要性#xff0c;作为其模板库中的一部分#xff0c;包含了常见的数据结构和算法#xff0c;是C的标准库 而我们今天要讲的String类#xff08;String底层是一个字符顺序数组的顺序表对象#xff0c;可以归类为容器#xff09;#xff0c;其实… 相信大家都知道STL在C中的重要性作为其模板库中的一部分包含了常见的数据结构和算法是C的标准库 而我们今天要讲的String类String底层是一个字符顺序数组的顺序表对象可以归类为容器其实其诞生于STL之前并不属于STL但是你却可以从中看到属于STL的一角相信学了String类之后在后面学习STL时vector等类对大家来说一定手到擒来 为什么学习String类
C语言中的字符串 C语言中字符串是以’\0’结尾的一些字符的集合为了操作方便C标准库中提供了一些str系列的库函数但是这些库函数与字符串是分离开的不太符合OOP的思想而且底层空间需要用户自己管理稍不留神可能还会越界访问。 在OJ中有关字符串的题目一般也是由String类形式出现很少有人去用C库中的字符串操作函数 标准库中的String类
String类基本了解
字符串是表示字符序列的类标准的字符串类提供了对此类对象的支持其接口类似于标准字符容器的接口但添加了专门用于操作单字节字符字符串的设计特性。string类是使用char(即作为它的字符类型使用它的默认char_traits和分配器类型(关于模板的更多信息请参阅basic_string)。string类是basic_string模板类的一个实例它使用char来实例化basic_string模板类并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。注意这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列这个类的所有成员(如长度或大小)以及它的迭代器将仍然按照字节(而不是实际编码的字符)来操作。 总结string是表示字符串的字符串类该类的接口与常规容器的接口基本相同再添加了一些专门用来操作string的常规操作。string在底层实际是basic_string模板类的别名typedef basic_stringchar, char_traits, allocator string;不能操作多字节或者变长字符的序列。在使用string类时必须包含#include头文件以及using namespace std;
String类常用接口说明
1. String类对象常用构造 我们分别在编译器中使用这些函数试试 相信通过这个演示大家已经知道string类的构造函数是如何使用的了不过我们一般不使用第三种其的重要性不如其他三个 2. string类容量操作 注意 1.size()与length()方法底层实现原理完全相同引入size()的原因是为了与其他容器的接口保持一致一般情况下基本都是用size()。 2 clear()只是将string中有效字符清空不改变底层空间大小。 3 resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个不同的是当字符个数增多时resize(n)用0来填充多出的元素空间resize(size_t n, char c)用字符c来填充多出的元素空间。注意resize在改变元素个数时如果是将元素个数增多可能会改变底层容量的大小如果是将元素个数减少底层空间总大小不变。 4 reserve(size_t res_arg0)为string预留空间不改变有效元素个数当reserve的参数小于string的底层空间总大小时reserver不会改变容量大小。
接下来也是用代码来举例子
3. string类对象的访问及遍历操作 代码演示
需要注意的是operator[]是重载运算符后面我们在自行实现string类时可以仔细观察
4. string类对象的修改操作 代码例子 注意
在string尾部追加字符时s.push_back( c ) / s.append(1, c) / s c’三种的实现方式差不多一般情况下string类的操作用的比较多操作不仅可以连接单个字符还可以连接字符串。所以实际意思就是好用对string操作时如果能够大概预估到放多少字符可以先通过reserve把空间预留好。
5.string类非成员函数
一般来说我们知道非成员函数就是没有写在类内部的函数所以像重载函数一些的函数都需要写在外部不然的话会出现无法改变函数的参数顺序的情况毕竟在我们先前写日期类时就出现过这些问题 关系操作relational operators有等于 不等于 小于 (小于等于 大于 大于等于
上面的几个接口大家了解一下下面的OJ题目中会有一些体现他们的使用。string类中还有一些其他的操作这里不一一列举大家在需要用到时不明白了查文档即可。
代码展示
牛刀小试 正确答案
class Solution {
public:string reverseOnlyLetters(string s) {int left 0;int right s.size() - 1;while (left right) {if (!isalpha(s[left])) {left;} else if (!isalpha(s[right])) {right--;} else {swap(s[left], s[right]);left;right--;}}return s;}
};容易错误答案
class Solution {
public:string reverseOnlyLetters(string s) {int begin 0;int end s.size() - 1;while (begin end) {if (!isalpha(s[begin]))begin;if (!isalpha(s[end]))end--;swap(s[begin], s[end]);begin;end--;}return s;}
};这里我们拿一个错误用例7_28本来由于其都是非英文字母所以其实本来应该直接循环结束也不会更改任何一个位置但是我们只考虑了可能会有1次非英文字母导致了在检查了一次之后就直接交换产生错误最后的结果直接错误而如果用if else一句一次循环只有一次判断虽然会麻烦一点但是不会出现这样的错误。也有人会说可以用while语句但是用while语句的话有时会超出时间所以我们这里也不推荐if else语句是我们比较建议的一种写法 正确答案
class Solution {
public:int firstUniqChar(string s) {int *a (int*)calloc(sizeof(int), 256);for (int i 0; i s.size(); i) {a[s[i]];}for (int i 0; i s.size(); i) {if (a[s[i]] 1) {free(a);return i;}}free(a);return -1;}
};正确答案
#include iostream
using namespace std;int main() {string s;getline(cin,s);if(s.empty())cout0endl;//如果是空串直接输出0size_t rfounds.rfind( );//找到最后一个空格if(rfound){couts.size()-1-rfoundendl;//如果找到了就用中间段相减得出结果}else{couts.size()endl;//没有空格现在的就是最后一个单词也就是现在的单词长度就是字符串最后一个单词}
}// 64 位输出请用 printf(%lld)正确答案
class Solution {
public:bool isPalindrome(string s) {string str;str.reserve(s.size()1);//提前reserve只是为了后面不用边加边扩容for(int i0;is.size();i){if(isalpha(s[i])){strtolower(s[i]);//如果是字母直接尾插小写的字母不管它小写的还是大写的}if(isdigit(s[i])){strs[i];//字母就直接尾插}}string str_beginstr;//保存反转前的strreverse(str.begin(),str.end());string rstrstr;//保存反转后的strif(rstrstr_begin){return true;}else{return false;}}
};正确答案
#include algorithm
#include stringclass Solution {
public:std::string addStrings(std::string num1, std::string num2) {if (num1 0)return num2;if (num2 0)return num1;//完美解决了0的三种情况std::string str;//用来存储相加后的字符串std::string::reverse_iterator rit1 num1.rbegin();std::string::reverse_iterator rit2 num2.rbegin();//从最后一位开始相加其实就是做竖式的过程int sum 0;//当位数int carry 0;//进位while (rit1 ! num1.rend() rit2 ! num2.rend()) {sum (*rit1 - 0) (*rit2 - 0) carry;carry sum / 10;str (sum % 10) 0;rit1;rit2;}//下面是防止两个一个长一个短的情况while (rit1 ! num1.rend()) {sum (*rit1 - 0) carry;carry sum / 10;str (sum % 10) 0;rit1;}while (rit2 ! num2.rend()) {sum (*rit2 - 0) carry;carry sum / 10;str (sum % 10) 0;rit2;}//如果最后加的那一下又有进位不能忘掉if (carry 0) {str carry 0;}std::reverse(str.begin(), str.end());//因为我们用是尾插不是头插所以最后要反转过来return str;}
};这道题我们要注意一个地方那就是我们是在字符串中加减所以我们不可以直接用字符加减而是要用其减去’0‘得到其原来的值 上面的是博主自己做的迭代器可能看上去很复杂麻烦下面是力扣的标准答案大家看一下应该会觉得很简洁
class Solution {
public:string addStrings(string num1, string num2) {int i num1.length() - 1, j num2.length() - 1, add 0;string ans ;while (i 0 || j 0 || add ! 0) {int x i 0 ? num1[i] - 0 : 0;int y j 0 ? num2[j] - 0 : 0;//这里避免了两个位数不同的问题int result x y add;ans.push_back(0 result % 10);add result / 10;i--;j--;}// 计算完以后的答案需要翻转过来reverse(ans.begin(), ans.end());return ans;}
};