串的处理
串的处理
一,题目要求
题目描述
在实际的开发工作中,对字符串的处理是最常见的编程任务。本题目即是要求程序对用户输入的串进行处理。具体规则如下:
- 把每个单词的首字母变为大写。
- 把数字与字母之间用下划线字符(_)分开,使得更清晰
- 把单词中间有多个空格的调整为 1 个空格。
输入描述
用户输入的串中只有小写字母,空格和数字,不含其它的字母或符号。每个单词间由 1 个或多个空格分隔。假设用户输入的串长度不超过 200 个字符。
输出描述
输出处理好的字符串。
输入输出样例
示例
输入
1 | you and me what cpp2005program |
输出
1 | You And Me What Cpp_2005_program |
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
二,解题思路
1,对空格的处理
举个例子:
比如在这里,我们要删除多余的空格,只保留一个空格
就是当i本身为空格时,将j指向i+1,删去j位置所在的空格,删除函数erase会自动返回j的下一个位置,用while循环判断直至j不是空格
2,对首字母大写的处理
我们可以发现除了第一个单词外,其他的首字母都出现在空格的后面,也就是我们在上面处理完空格之后的j处,变为大写即可
3,对下划线的处理
下划线出现在字母和数字之间,只有两种情况
- 左面是字母,右面是数字
假定我们当前的下标为i指向数字,现在指向2,那么i-1需要是字母a-z或A-Z
- 右面是字母,左面是数字
假定我们当前的下标为i指向数字,现在指向5,那么i+1需要是字母a-z或A-Z
三,对应知识点
1,包含头文件的区分
#include <string.h>
C语言的头文件,包含比如
strcpy
之类的字符串处理函数。注意C语言里没有string类的概念,不要弄混。不可以定义string s;可以用到
strcpy
等函数#include <string>
C++的头文件,包含
std::string
的定义,属于STL范畴可以定义string s;可以用到
strcpy
等函数#include <cstring>
C++版本的头文件,和C语言版本的
<string.h>
对应,将C语言的函数定义在std
命名空间内。不可以定义string s;可以用到
strcpy
等函数
在此处我们选择
2,c++中如何读入字符串
#此部分参考:https://exp-blog.com/lang/cpp-de-liu-chong-chang-yong-shu-ru/
①cin
用法1: 最基本,也是最常用的用法,输入一个数字或字符(不接受空字符作为字符输入,当输入字符为空字符时,会不断重复要求输入,直至输入字符非空后,通过回车结束输入)
1 | cin>>a>>b; // cin允许这种"连续输入"模式 |
用法2: 接受一个字符串,遇“空格”、“TAB”、“回车”都结束:
1 | char a[20]; |
②cin.get()
用法1: cin.get(字符变量名)
可以用来接收字符:
1 | ch=cin.get(); //或者cin.get(ch); |
用法2: cin.get(字符数组名,串长)
用来接收一行字符串,可以接收空格:
1 | char a[20]; |
用法3: cin.get(无参数)
没有参数,主要是用于舍弃输入流中的不需要的字符,多用于舍弃前一次输入时放在输入缓冲区的回车。
③cin.getline()
用法1: 接受一个字符串,可以接收空格并输出:
1 | char m[20]; |
用法2: 当用在多维数组中的时候,也可以用cin.getline(m[i],20)
之类的用法:
1 | char m[3][20]; |
注:
cin.getline()
功能的扩展说明
cin.getline()
实际上有三个参数,cin.getline(char对象地址,串长,’结束字符’)
① 当第三个参数省略时,系统默认为’\0’
② 如果把例子中cin.getline()
改为cin.getline(m,5,’a’);
当输入jlkjkljkl
时,输出jklj
; 输入jkaljkljkl
时,输出jk
③cin.getline()
至少要有前2个参数,且只能和char(或char*)定义的字符串地址搭配,不能和string定义的字符串地址搭配
④getline()
接受一个字符串,可以接收空格并输出(需 #include
1 | string str; |
注:
①getline()
和cin.getline()
类似,但是cin.getline()
属于istream
流,而getline()
属于string流,是不一样的两个函数。
②getline(cin,string对象地址)
中的字符串地址只能和string定义的字符串地址搭配,不能和char(或char*)定义的字符串地址搭配。这与cin.getline()
相反。
⑤gets()
用法1: 接受一个字符串,可以接收空格并输出(需 #include <string>
):
1 | char m[20]; |
注:gets(char对象地址)
gets()只能和char(或char*)定义的字符串地址搭配,不能和string定义的字符串地址搭配
用法2: 类似cin.getline()
里面的一个例子,gets()同样可以用在多维数组里面:
1 | for(int i=0;i<3;i++) |
⑥getchar()
1 | ch=getchar(); //不能写成getchar(ch); |
注:
getchar()
是C语言的函数,C++也可以兼容,但是尽量不用或少用
本题中,因为我们需要用到STL更方便地操作字符串,所以我们采取getline
,同时不要忘记包含头文件#include <string>
1 | string str; |
3,c++中的string库函数
#参考文章:http://snowline.info/STL_gen.htm
①说明和初值:
1 | string str; |
②串连接:
可以使用+或+=连接两个或多个字符串,这些字符串,可以是const char *
、char *
或string型的。有多个串时,前两个串中必须有一个是string型的。
1 | string str1, str2 ; |
③串查找:
string容器提供了多种查找方法,这里只介绍最简单的正反向查找。
1.正向查找:查找串中出现指定子串的位置,使用find()函数,第一个参数表示子串。返回一个整型值,表示出子串的位置。大于等于0时表示出现了子串,否则表示没有出现。
1 | str = "abcdefgcd"; |
2.反向查找:从后面开始,查找串中出现指定子串的位置,使用rfind()函数,第一个参数表示子串。返回一个整型值,表示出子串的位置。大于等于0时表示出现了子串,否则表示没有出现。
1 | str = "abcdefgcd"; |
④串替换:
把一个串中的子串,替换为另一个串,使用replace()函数,第一个参数是替换位置,第二参数是替换长度,第三个参数是替换子串。替换串和被替换的子串长度可以不等。
1 | string str = "abcdefgcd"; |
⑤串插入:
在串的中间插入一个子串,使用insert()函数,第一个参数是插入位置,第二个是插入子串。
1 | string str = "abcdefgcd"; |
⑥串删除:
在串的中间,删除若干个字符,使用erase()函数,第一个参数是删除位置,第二个参数是删除长度。
1 | string str = "abcdefgcd"; |
注意:串的替换,插入,删除操作中,操作位置必须是0到字串长度的范围之内,超过这个范围,将会引起异常
⑦取子串操作:
从一个串中取子串的操作,使用substr()函数,第一个参数表示开始位置,第二个参数表示取的长度。如果不包含第二个参数,一直取到串的结束。
1 | string str = "abcdefgcd"; |
string没有提供left,right函数,来从左边和右边取子串,造成了一些不便,需要采用技巧来实现。
取左串:str.substr(0, n) ;
取右串:str.substr(str.size()-n);
⑧字串比较:
比较两个字串,使用compare函数,可以比较全字串,或串中若干个字符。字符串比较是按字符的ASCII码进行对比。
= 返回 0 > 返回 1 < 返回 -1
1 | string str = "abcdefgcd"; |
⑨其它常用操作:
对于string,还有一些常用的操作。
返回字串长度的size(),例:len = str.size();
下标操作at(),例:c = str.at(1);str.at(2)= "5";
下标操作也可以用[],例:c = str[1];str[2]= "5";
四,代码
1 |
|