对于一个或多个字符构成的序列,除了用字符数组存储以外,还可以用C++ string类来进行字符串的处理。
要使用string 类,必须在程序中包含头文件cstring。string类的定义隐藏了字符串的数组性质,让我们能够像处理普通变量那样处理字符串。
使用string类型串具有一些独特的优势。 首先, 它在内存使用上是自动的, 需要多少, 开辟多少, 并且能够根据字符串大小的变化自动调整所开辟的内存,无需考虑越界的情况; 此外, string类附带了功能丰富的函数,方便进行一系列的复杂操作。
下面我们还是先从声明、赋值以及取值三方面来简单了解string 类的使用。
二、字符串的基本操作 1、声明:string 字符串名; 例如:string a; / string a,b; 字符串初始状态为空串。
Copy
2、赋值:
| 方式 | 含义 |
|---|---|
| cin >> a; | 用cin读取一段字符串,并将它赋值给a。缺点:无法识别空格和换行符。 |
| getline ( cin,a); | 可识别空格的赋值方式。 |
| getline(cin,a,'分隔符'); | 这里的分割符就相当于是“结束符”,我们是在输入的字符串结尾额外再加一个符号,构成a的全部内容。 |
| string a1(a); | 定义了一个字符串a1,并将它初始化为和字符串a一样的内容(保证在此之前a已经定义并初始化过了)。 |
| string a2=a+a1; | 定义了一个字符串a2,并将它的内容初始化为a和a1拼接在一起的结果。 |
3、取值:PS: string类变量在存储字符时,方式时和字符数组一样的,依然是把每个字符拆分开来单独放置在对应的“小房子”中。
字符串的取值很简单,一个cout指令直接搞定。下面举一个简单的完整程序,帮助大家了解一下字符串的一般操作。
#includeusing namespace std; int main() { string a; cin>>a; string a1(a); string a2=a; string a3(5,'0'); string a4=a2+a3; cout<
Copy
正在上传…重新上传取消
4、关于下标:对于一个string 类变量a,当你采用cin方式赋值时,“一千个人眼里有一千个哈姆雷特”,一个人赋值的结果也有成百上千种可能---每个人塞到a里面的字符串内容是不同的,字符串的长度也是不同的。所以呢,想要获取实际字符串长度,需要借助其他函数:
(1) a.size() (2)a.length()
Copy
上述两个函数的功能都是返回a中字符的实际个数。知道了个数,具体每一个元素的下标也就一清二楚了。这里同样举一个具体的程序:
#includeusing namespace std; int main() { string a; cin>>a; cout<
Copy
正在上传…重新上传取消
三、例题讲解 1、数字和输入一个由数字组成的字符串,求各个位上数字的和。
输入格式:输入一行,包含一个数字字符串。
输出格式:输出一个正整数,代表所有数字之和。
样例:
输入数据#112345
Copy
输出数据#115
Copy
【分析】:
(1)题目没有明确规定所输入字符的个数范围,所以选择用string类进行存储。
(2)由数字字符求对应数学上的数值之和,涉及到一个关于ASCII码值的操作。因为字符’0’的值是指它的ASCII码值,即48;而在数学上它的对应值是0。这之间相差了48的大小。
(3)求和需要单独的变量来存储和。
【参考代码】:
#includeusing namespace std; int main() { string a; int s=0,len; cin>>a; len=a.size(); // len代表输入字符的长度 for(int i=0;i Copy
2、输入输出PS:我们在对字符串中每一个元素进行操作时,for循环条件是i
读取一行句子,句子中的单词是由一个或多个空格分隔的,句子首尾没有空格。
请顺序输出句子中的每个单词,一行一个。例如句子是I love tls
样例:
输入数据#2I love tlsCopy
输出数据#2I love tlsCopy
【分析】:
(1)读取的句子中含多个空格,所以是肯定不能用简单的cin指令来给字符串赋值了。对于这种可能存在连续或间断的空格数的题目,getline(cin,a); 的赋值方式也不是一种可取的方式,它的工作量较大。
(2)这里我们采取一种全新的赋值方式:while(cin>>a)(其中a是字符串类型)。while(cin>>a)的作用是循环输入数据,在读不到的时候结束循环,原理类似死循环,在竞赛题中经常会遇到这种赋值方式的题型。
(3)由于cin指令无法识别空格,所以我们在输入句子过程中,每一次输入空格,就相当于给a赋值工作的一次循环结束了,此时直接cout<
【参考代码】:
#includeusing namespace std; int main() { string a; while(cin>>a) { cout< Copy
3、车牌号【注意】:while(cin>>a)的赋值方式本质就是个无限循环,所以某些特殊情况下是没有办法运行出来测试数据的对应结果的。怎么能将这个无限循环变成“可控制的有限循环”呢?这个就要用到我们的文件操作了。有兴趣深究的同学可以自行查阅相关资料了解这一功能。
众所周知中国的车牌号是由数字和字母组成的5位字符串,拓拓星球的车牌号也是由数字和字母组成的,但是位数是不固定的,车牌的总长度不超过1000都算合法,所以车牌中有很多字符是重复.
如果车牌中某个字符重复出现的次数恰好是素数,那这个车牌就称得上是一个”吉利”的车牌。请你统计出拓拓星球的一个车牌号中哪些字符出现的次数是素数,并按照字符的ASCII码值升序输出这些字符。
输入格式:输入一行,一个字符串表示一个车牌号,字符串中只包含数字字符、大写字母和小写字母。
输出格式:输出一行,对于每个车牌统计出字符出现的次数为素数的字符,按照ASCII升序输出,每个字符之间用一个空格隔开,如果没有这样的字符则输出empty 。
输入数据#3ABCDECopy
输出数据#3emptyCopy
输入数据#4AABBCopy
输出数据#4A BCopy
【分析】:(1)这是一道字符串+桶计数+素数判断的综合题目。第一步:我们要统计出每个字符(大、小写字母以及数字)的出现次数 ;第二步:按照ASCII码值从小到大的顺序,一次判断每一个出现次数值的性质。为方便起见,可将素数判断模块打包成函数,直接调用。
【参考代码】:
#includeusing namespace std; //第一步:构造判断素数的函数 bool ss(int n)//素数判断的函数 { if(n==1) return 0; if(n==2) return 1; for(int i=2;i*i<=n;i++) //只讨论2-n的平方根这个范围内的情况 { if(n%i==0) return 0; } return 1; } int a[150];//a数组专门用来计数,一定要开大点,因为我们统计的对象有大小写字母和数字 bool flag;//flag用来标记是否存在出现次数为素数的字符 int main() { //第二步:输入字符串并进行桶计数 string s; cin>>s;//车牌号不包含空格,可采用cin方式赋值 for(int i=0;i Copy
4、最长连续重复字符请统计输入的字符串中最大连续重复字符的个数,要求统计找出给定字符串中哪些字符连续出现的次数最多,并且要统计这些字符一共连续出现了多少次。例如:字符序列为 AAA222BBAAAaa,则在这个字符序列中,字符 A 和字符 2 连续出现的次数最多,都是 3 次。
输入格式:共两行,第一行为字母序列中的字母个数 n(1≤N≤1000),
第二行为 n个字符组成的字符串序列。输出格式:共两行,第一行为最多连续出现次数最多的字符,若有多个用空格分隔,输出顺序为他们在字符串中的先后顺序。第二行为连续出现重复的最大次数。
输入数据#513 AAA222BBAAAaaCopy
输出数据#5A 2 3Copy
【分析】:
(1)这是一道2019年合肥市赛的真题,考察了连续性问题在字符串中的应用。由于题目给定了字符个数,所以既可以用字符数组,也可以用字符串(存储时注意下标的处理)。
(2)题目要求的内容有两项:最多连续出现次数最多的字符(按照在字符串中的先后顺序依次输出),出现重复的最大次数。由于连续出现次数最多的字符可能不止一种,且同一字符可能多次出现连续最大值但只能输出一遍,无形中增加了解题的难度。
(3)本题解题的大致过程为:根据连续性求出最长连续次数--》依次求出字符串中的字符的连续次数,若等于次数最大值,且之前没有输出过,则输出该字符,并做标记,以防止重复输出。
(4)在连续性的处理过程中,我们将相邻的两个字符(a[i]和a[i+1])进行比较,如果值相等则继续计数,否则说明a[i]的连续中断,即可处理此时的s值。
同时,为了方便讨论末尾字符a[n]的相关连续性,我们将a[n+1]赋值为空格字符,由于题目给定字符范围是33-126,空格字符不在此范围内,所以不会影响连续次数的值,并能保证在讨论到a[n]与a[n+1]时一定是连续中断的,这样就可以把a[n]的连续出现次数直接纳入考虑,而不需要单独在for循环外讨论。
【参考代码】:
#includeusing namespace std; bool flag[130]; // 用于在输出时标记某一字符是否输出过 char a[1001]; // 字符数组,存储n个字符 int main() { int n; cin>>n; for(int i=1;i<=n;i++) // 输入n个字符 { cin>>a[i]; } a[n+1]=' '; //结尾加一个不影响连续性结果的字符,方便后续讨论 int maxc=0,s=1;//maxc代表连续性最大值,s代表当前字符的连续次数,值至少为1 for(int i=1;i<=n;i++) //注意循环范围是1-n,也就是把a[n]与a[n+1]的组合情况也纳入考虑 { if(a[i]==a[i+1]) //如果连续,s值增加 { s++; } else //如果连续中断,更新当前次数的最大值,并初始化s为1 ,重新统计下一段的连续次数 { maxc=max(maxc,s); s=1; } } s=1;//这句话千万不能丢哦!它影响到下面for循环的s初值 for(int i=1;i<=n;i++) { if(a[i]==a[i+1]) { s++; } else { if(s==maxc && flag[a[i]]==0) //中断结束,讨论当前次数是否是最大值,并且该字符没有输出过 { cout< Copy
四、推荐题单字符串练习1
大小写转换
大鹏在打字简单加密
Dota系列─第一滴血
颠倒的句子
出现次数最多的小写字母
最大连续组长度(long)
字符串压缩
拓展题:
字母概率Your Ride Is Here
ISBN号码
笨小猴
气球MM
字符统计
统计字母出现次数
单词缩写
字符串解压
字符串展开



