当前位置:网站首页>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);的效率因为它是深拷贝
边栏推荐
- 为不同类型设备构建应用的三大更新 | 2022 I/O 重点回顾
- c语言(结构体)定义一个User结构体,含以下字段:
- DC-7靶机
- Software testing knowledge reserve: how much do you know about the basic knowledge of "login security"?
- 港科大&MSRA新研究:关于图像到图像转换,Fine-tuning is all you need
- Value range of various datetimes in SQL Server 2008
- Introduction to yarn (one article is enough)
- 职场经历反馈给初入职场的程序员
- Cloud acceleration helps you effectively solve attack problems!
- 字符串常量与字符串对象分配内存时的区别
猜你喜欢

Convert numbers to string strings (to_string()) convert strings to int sharp tools stoi();

Jstat pour la commande JVM: voir les statistiques JVM
![[FPGA tutorial case 13] design and implementation of CIC filter based on vivado core](/img/19/1a6d43c39f2cf810ba754ea9674426.png)
[FPGA tutorial case 13] design and implementation of CIC filter based on vivado core

SubGHz, LoRaWAN, NB-IoT, 物联网

生活中的开销,怎么记账合适

3531. Huffman tree

JVM command - jmap: export memory image file & memory usage

JMeter's own functions are not enough? Why don't you develop one yourself

You don't know the complete collection of recruitment slang of Internet companies

JVM命令之- jmap:导出内存映像文件&内存使用情况
随机推荐
【GNN】图解GNN: A gentle introduction(含视频)
[SOC FPGA] peripheral PIO button lights up
10W word segmentation searches per second, the product manager raised another demand!!! (Collection)
Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens
Chain storage of stack
Redis(一)——初识Redis
[FPGA tutorial case 14] design and implementation of FIR filter based on vivado core
How to set up in touch designer 2022 to solve the problem that leap motion is not recognized?
Calculation model FPS
职场经历反馈给初入职场的程序员
CloudCompare-点对选取
Subghz, lorawan, Nb IOT, Internet of things
JVM命令之- jmap:导出内存映像文件&内存使用情况
Qtthread, one of many methods of QT multithreading
3531. Huffman tree
从“跑分神器”到数据平台,鲁大师开启演进之路
当我们谈论不可变基础设施时,我们在谈论什么
Audio distortion analysis of DSP and DAC based on adau1452
Niuke Xiaobai monthly race 52 E. sum logarithms in groups (two points & inclusion and exclusion)
Cloud acceleration helps you effectively solve attack problems!