《C++ primer》-第三章-《字符串,向量和数组》-string篇

大约5400字,认真浏览的话需要15分钟,如果coding一遍,大约需要一个小时。如有错误,请与我联系。

导读:这一章节的内容还是蛮有意思的,刷新我对数组,容器的一些看法吧。
参考书籍,课程如下(如有侵权,请及时和我联系):
《C++ primer》
《算法笔记》第二版

视频参考
中国大学mooc 程序设计与算法(三)C++面向对象程序设计

标准库类型string,表示可以变长的字符序列,使用string必须先包含string头文件。作为标准库的一部分,string定义在命名空间std中。其实我觉得string开始有点像面向对象的一些味道。相对于C风格,不再使用字符数组去充当角色。其实很容易就能看到源码,在dev-cpp中按住crtl点击string这个单词就能看到源码啦!它相当于封装好的类库,用户使用十分方便。

以下我将会讲一下string的使用方法以及string常用方法的一些代码

关于初始化,有别于C风格。
string的初始化显得多样。其实这里的每一个内容,都是值得去进行深究的,比如。更过细节请参考《STL源码剖析》如果有时间,我一定会丰富这篇文章的内容。

初始化的方式如下:

string s1;
string s2(s1);//拷贝初始化,s2是s1的副本 
string s1=s2;
string s3("values");
string s3="values";//这是学生的常规写法,直接拷贝初始化 
string s4(10,'c');//连续初始化,s4="cccccccccc"; 

在对象上的一些操作:
定义和输入

string str1;
string str2;
cin>>s1>>s2;
getline(cin,str1);//很有用,在输入字符串,并且去进行输出的时候,这是一个利器,解决的吃字符的问题

现在看起来输入很简单,没有什么可以讲的,但是坑点非常多。输入不当,导致输出的结果就会显得差强人意。比如pat-1050-password,这一道题目,就需要注意,如果仅仅通过cin去对字符串去进行输入,那么基本上是全错,测试点基本上过不了。关于字符串的输入和输出很值得去讲解,引用一篇我认为非常好的博文。输入输出总结

不妨看看输入不当,导致输出差强人意的例子是什么样子的:

#include 
using namespace std;
int main(){
	string str;//我输入的是"hello world"
	cin>>str;
	cout<<str; //输入的仅仅只有hello 
	return 0;
} 
输入:
hello world
输出:
hello

《C++ primer》-第三章-《字符串,向量和数组》-string篇_第1张图片
如果采用了**getline()**就能解决很多问题了。

#include 
using namespace std;
int main(){
	string str;//我输入的是"hello world"
	cin>>str;
	string str;
	getline(cin,str);
	cout<<str1; 
	return 0;
}

//以输入hello world为例 

没有出现吃字符的现象《C++ primer》-第三章-《字符串,向量和数组》-string篇_第2张图片

字符串的操作以及库函数(我很认为我的总结时很全面的):

①:字符串的比较
string对象的比较:string对象的比较是按照字典顺序进行比较,真的是很有用。
比如:给你一天的时间点:23:45:33 与21:33:56,虽然整体的上存在字符(:),但是只要数位长度相同,其实字符是可以去进行比较的。通常题目没有这么坑,如果数位不齐,那就去补齐,那这一类的题目就真的恶心了一点了,需要自己循环补上。
参考:1006 Sign In and Sign Out (25分)(当时我就傻傻的写函数去进行比较,其实直接可以对字符串进行比较,因为字符串是按照字典顺序的)
如何通过比较:通过逻辑运算符:>=,<=,!=,==,>,<

②:字符串的赋值与相加

string st1=(10,'c');//此时str1="cccccccccc"
string str2="hello world";
str1=str2;//str2的副本替代了str1
string str3=str1+str2;//字符串相加,注意字符串的相加需要类型享同,否则无法匹配

③:字符串的字符处理(一大堆处理单个字符的函数,我就不一一列举了):

在介绍的字符串的字符单个处理的时候,介绍一些for-each循环。基于范围的for-each语句

//语法的形式如下
for(declaration:expersion)
	statement; 

字符处理的函数:
《C++ primer》-第三章-《字符串,向量和数组》-string篇_第3张图片
字符处理示例:

#include 
#include 
#include 
using namespace std;
int main(){
	string str1="Hello world123,this is a new world";
	//这个for循环无法对初始的字符串去进行修改 
//	for(auto c:str1)
//		cout<
	//上面就是简单的for-each循环,其实for-each循环有点像函数的感觉
	//接下来就是字符的处理
	int cnt;//统计空白字符的个数 
	for(auto c:str1)
		//ispunct(c) //判断字符c是否是符号,比较,!,。等
		//if(ispunct(c)) //统计符号的个数 
		if(isspace(c)) //统计空格的个数 
			cnt++;
	cout<<cnt; 
	

使用范围的for语句去改变字符串中的字符

#include 
#include 
#include 
using namespace std;
int main(){
	string str1="Hello world123,this is a new world";
	//如何将str1的字符串全部转化为大写 
	for(auto &c:str1)
		c=toupper(c);
	cout<<str1; 
	cout<<endl;
	for(auto &a:str1)
		a=tolower(a);
	cout<<str1;
}

输出结果:

HELLO WORLD123,THIS IS A NEW WORLD
hello world123,this is a new world

④:字符的索引:比如在一个长串中定位到某一个单个字符
方式一:直接类似于数组,下标直接去索引
方式二:调用.at(i)函数,指明第i个字符

代码示例如下:

#include 
#include 
#include 
using namespace std;
int main(){
	string str;
	getline(cin,str);
	//如何通过索引的方式去对输入的一行字符串进行处理
	for(int i=0;i<str.size();i++){
		cout<<str[i];
	}
	cout<<endl;
	for(int i=0;i<str.size();i++){
		cout<<str.at(i);
	}
	return 0;
} 
输入:hello world

输出为:hello world
hello world

⑤:字符串的常用函数及其操作(无非就是一些增删改查)
empty();//判断是否为空
size();//返回字符出的长度
length();//同上返回字符串的长度
substr(pos,n);//获取字符串的字串.从pos的索引开始,获取长度为n的子串
insert();//插入子串
append(“所要添加内容”);//字符串末尾添加内容
replace(range,args);//在range范围内的内容删除,换成args指定的字符
erase(pos,n);//删除从pos开始的n个字符
find(“所要查找的内容”);//查找操作。返回值是子字符串在目标字符串第一次出现的下标
rfind(“所要查找的内容”);//查找操作。返回值是子字符串在目标字符串最后一次出现的下标(同样还是返回索引下标)

字符串的比较,这个是比较重要的,类似于c语言的strcmp()
主要是以下函数:
**s1.compare()**的参数形式如下:

< 返回负数 (通常是-1)
= 返回0 > 返回整数(通常是1)

函数的参数列表有如下三种形式:

s2    //表示的是:s1与s2去进行比较 
pos1,n1,s2    // 将s1中pos1开始的n1个字符串与s2去进行比较 
pos1,n1,s2,pos2,n2   // 将s1中pos1开始的n1个字符串与s2从pos2的n2个连续字符串去进行比较字符串去进行比较 

代码示例:

#include 
using namespace std;
int main(){
	string s1="hello";
	string s2="Hello";
	string s3="abcd";
	string s4="world";
	
	cout<<s1.compare(s2)<<endl;
	cout<<s1.compare(s3)<<endl;
	cout<<s1.compare(s4)<<endl;
	
	cout<<s1.compare(0,3,s2)<<endl;//取s1的索引为0,开始长度为3的连续字符与s2去进行比较 4
	cout<<s1.compare(0,3,s4)<<endl;
	
	cout<<s1.compare(0,3,s2,2,2)<<endl;//取s1的索引为0,开始长度为3的连续字符与s2索引为2,开始长度为2进行比较
	//s1="hel",s2="ll",显然s1
	return 0;
}
输出结果如下:
1
1
-1
1
-1
-1

⑥:关于数值转换
在很多的算法题目中,输入的数可能太大,导致输入类型的选择不能确定,那么刚开始可以定义为字符串,然后字符串转成字符
在前面我已经介绍了如何对字符串的字符去进行进行索引

//这是c语言的写法 
字符转成数字:-'0'    //减去一个偏移量,可以转化成数字
数字转换成字符:+'0'  //加上一个偏移量,可以从数字转换成字符

string类型的数值转换函数

to_string(val);//将任一类型转换成字符串类型 
stoi();//字符串转化为整数,但是注意,这个字符串的内容必须是数组,否则类型检测就会抛出异常
stof();//字符串转化成浮点数 

代码示例如下:
我们可以通过typeid(变量名).name()去检测出变量名的类型。但是需要注意加上头文件#include

#include 
#include 
using namespace std; 
int main(){
	string s1="hello wrold";
	string s2="123123";
	string s3="123123.234";
	int value=1234;
	
	string vTos=to_string(value);
	int sToi=stoi(s2);
	float sTof=stof(s3);
	cout<<typeid(vTos).name()<<endl;//数字类型转换成字符串类型
	cout<<typeid(sToi).name()<<endl;//字符类型转换成整型
	cout<<typeid(sTof).name()<<endl;//字符类型转换成浮点型 
}

输出结果如下:
Ss
i
f

其中Ss:表示的是字符串类型
i:表示的是整形
f:表示的是浮点型

你可能感兴趣的:(《C++,primer》)