当前位置:网站首页>string(讲解)
string(讲解)
2022-07-07 01:45:00 【韩悬子】
目录
1.标准库里面的string类了解
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedefbasic_string<char, char_traits, allocator>string;(报错是basic_string不用太注意)
- 不能操作多字节或者变长字符的序列。在使用string类时,必须包含#include头文件以及using namespace std;
2.sting常用的构造函数用法
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
return 0;
}
这个是最常用的,作用是管理动态增长的字符数组,以\0为结尾。
但是注意这里是不能编译成功的
因为在使用string类时,必须包含#include头文件以及using namespace std;(因为c++标准库都是存放在std里面的)
如果不包std,可以按下面用法
代码
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
std::string s1;
return 0;
}
不过当然啦,这里我们为了使用方便我们就把std全部展开
string还有一种写法,就是
#include<iostream>
using namespace std;
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
string s2("hello world");
return 0;
}
这种就是用常量字符串来初始化,这个使用new或者malloc出来的,然后就把这个数组拷贝过去,这种有个最大的优点就是它这个是动态增长的,你搞个数组它的大小是定死的,但是string的这个可以动态增长,原理也很简单,因为是扩容
用法
#include<iostream>
using namespace std;
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
string s2("hello world");
s2 += "!!!!!";
cout<<s2<<endl;
return 0;
}
打印结果
不过当然除了这种还有一种拷贝构造
代码
#include<iostream>
using namespace std;
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
string s2("hello world");
s2 += "!!!!!";
cout << s2 << endl;
string s3(s2);
string s4 = s2;
return 0;
}
只要拿一个以存在的对象,去初始化一个未存在的对象,这个都是拷贝构造
还有一种写法,就是想要用这个字符串前n个来初始化,后面的不要
代码
#include<iostream>
using namespace std;
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
string s2("hello world");
s2 += "!!!!!";
cout << s2 << endl;
string s3(s2);
string s4 = s2;
string s5("https://editor.csdn.net/md?articleId=125475746", 4);
cout << s5 << endl;
return 0;
}
运行结果
还有一种是从某个字符串n位置做起始,拷贝n个字符
代码
#include<iostream>
using namespace std;
#include<string>
//管理动态增长的字符数组,以\0为结尾
int main()
{
string s1;
string s2("hello world");
s2 += "!!!!!";
cout << s2 << endl;
string s3(s2);
string s4 = s2;
string s5("https://editor.csdn.net/md?articleId=125475746", 4);
cout << s5 << endl;
string s6(s2, 5, 6);
cout << s6 << endl;
return 0;
}
运行结果
不过这里如果我只要了6个,要是我要100个会报错吗?
答案是不会,超过字符串大小会是有多少给多少
3.string小练习
我们把string的用法讲的差不多了我们来做下题吧
题链接
题描述
给你一个字符串 s ,根据下述规则反转字符串:
所有非英文字母保留在原有位置。
所有英文字母(小写或大写)位置反转。
返回反转后的 s 。
不过当然想做这道题最主要的是会遍历字符串
前面没讲string的遍历方式
第一种遍历方式的代码
1.下标+[]
void test2()
{
string s1("hello");
cout << s1.size() << endl;//这个是不包含\0的
//第一种方式 下标+[]
for (size_t i = 0; i < s1.size(); i++)
{
//s1.operator[](i);
cout << s1[i] << " ";
}
cout << endl;
}
这个要注意的是这里的size是不包含\0的所以打印是5个,还有遍历方式也是不同这个不是数组,这个相当于调用函数,相当于调用s1.operator;
运行结果
第二种遍历方式
2.迭代器
void test3()
{
string s1("hello");
//迭代器
string::iterator it=s1.begin();
while (it != s1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
这种是迭代器遍历,迭代器是像指针一样的东西或者就是指针,s1.begjn()是代表着起始的位置,而end()是代表着结束的下个位置,其实就是左闭右开。
这里还有一个问题就是能不能把it != s1.begin()改成it < s1.begin(), 在1某些情况可以,比如它们空间是连续的,但是不推荐<的这种写法,因为你的内存不一定是连续的,一旦不是连续的你就会出现错误了
运行结果
第三种遍历方式
void test4()
{
string s1("hello");
for (auto ch : s1)
{
cout << ch << " ";
}
}
3.范围for
原理很简单,其实底层原理就是替换成迭代器
运行结果
题目答案
下标+[]的写法
class Solution {
public:
bool isLetter(char ch)
{
//只要是26位字母就返回真
if( ch >='a' && ch<='z')
return true;
else if(ch>='A' && ch<='Z')
return true;
else
return false;
}
string reverseOnlyLetters(string s) {
int left=0,right=s.size()-1;
while(left<right)
{
//是26位字母就不动,直接交换,如果不是就按要求加加减减
while(left<right && !isLetter(s[left]))
++left;
while(left<right && !isLetter(s[right]))
--right;
swap(s[left],s[right]);
++left;
--right;
}
return s;
}
};
迭代器的写法
代码
class Solution {
public:
bool isLetter(char ch)
{
if( ch >='a' && ch<='z')
return true;
else if(ch>='A' && ch<='Z')
return true;
else
return false;
}
string reverseOnlyLetters(string s) {
string::iterator leftit=s.begin();
string::iterator rightit=s.end()-1;
while(leftit<rightit)
{
while(leftit<rightit && !isLetter(*leftit))
++leftit;
while(leftit<rightit && !isLetter(*rightit))
--rightit;
swap(*leftit,*rightit);
++leftit;
--rightit;
}
return s;
}
};
4.迭代器
1.正向迭代器
这个很简单的就是前面讲遍历字符串的那个迭代器就是正向迭代器
代码
void test3()
{
string s1("hello");
//迭代器
string::iterator it=s1.begin();
while (it != s1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
2.反向迭代器
这个和名字相同,正向遍历是从前面遍历,那么反向遍历就是从后面开始遍历的
代码
void test5()
{
string s1("hello");
string::reverse_iterator rit = s1.rbegin();
while (rit!=s1.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;;
}
运行结果
3.加了const的迭代器
代码
void test3()
{
string s1("hello");
//迭代器
string::iterator it = s1.begin();
while (it != s1.end())
{
(*it) += 1;
cout << *it << " ";
++it;
}
cout << endl;
it = s1.begin();
while (it != s1.end())
{
(*it) -= 1;
cout << *it << " ";
++it;
}
cout << endl;
}
//管理动态增长的字符数组,以\0为结尾
int main()
{
test3();
return 0;
}
因为迭代器是像指针一样的东西或者就是指针,所以他可以可读可写
下面是运行结果,上面代码的意思是让hello每一位-1,然后通过加1来变回hello
所以这里正常的版本,有了这个版本也有const的版本了
const的版本就只能只能可读了,不能可写了
代码
可以看到其实迭代器不只是二种其实是四种,正向迭代器,const正向迭代器,反向迭代器,const反向迭代器
不过当然有人可能觉得迭代器太麻烦了要打那么多代码,这时候有个好办法
那就是auto
代码
5.string的swap和库里面的swap的区别
代码
#include<iostream>
using namespace std;
void test1()
{
string s1("hello world");
string s2("hello");
s1.swap(s2);
swap(s1, s2);
}
int main()
{
test1();
return 0;
}
请问它们的区别是什么
s1.swap(s2);的效率高因为它是交换二个的指针
swap(s1, s2);的效率因为它是深拷贝
边栏推荐
- Sequential storage of stacks
- vim映射大K
- Database notes 04
- Party A's requirements for those who have lost 800 yuan
- 3428. 放苹果
- Implementation of VGA protocol based on FPGA
- postgresql 数据库 timescaledb 函数time_bucket_gapfill()报错解决及更换 license
- New Year Fireworks code plus copy, are you sure you don't want to have a look
- Experience of Niuke SQL
- Ideas of high concurrency and high traffic seckill scheme
猜你喜欢
随机推荐
Redisl garbled code and expiration time configuration
Crudini 配置文件编辑工具
"Parse" focalloss to solve the problem of data imbalance
基于FPGA的VGA协议实现
A very good JVM interview question article (74 questions and answers)
从“跑分神器”到数据平台,鲁大师开启演进之路
The boss always asks me about my progress. Don't you trust me? (what do you think)
Rk3399 platform development series explanation (interruption) 13.10, workqueue work queue
C面试24. (指针)定义一个含有20个元素的double型数组a
Convert numbers to string strings (to_string()) convert strings to int sharp tools stoi();
win系统下安装redis以及windows扩展方法
职场经历反馈给初入职场的程序员
测试开发基础,教你做一个完整功能的Web平台之环境准备
Test the foundation of development, and teach you to prepare for a fully functional web platform environment
【OpenCV】形态学滤波(2):开运算、形态学梯度、顶帽、黑帽
LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标
Subghz, lorawan, Nb IOT, Internet of things
VScode进行代码补全
New Year Fireworks code plus copy, are you sure you don't want to have a look
k8s运行oracle