字符串

本篇将介绍一种新的变量类型:字符串

字符串与字符数组不同的地方就在于:字符数组的大小在声明时就已经定了下来;而字符串的大小是可以改变的,当你往字符串里面添加元素时,字符串的大小也会相应地改变。下面介绍对于字符串的操作(转载自YCOJ):


s.size(); // 得到字符串长度

s.find(); // 查找字符或子串所在位置,若存在子串则返回子串开头字符下标,否则返回-1

    s.find('a');
    s.find("hello");
    s.find("hello", 2);//从字符串s下标2往后面查找

s.replace(); // 字符串s某个部分替换成另一个字符串

    s.replace(0, 5, "hello");//字符串s从下标0开始,长度为5的部分替换成"hello"

s.substr(); // 取字符串某个部分(子串)

    s.substr(2);    //取字符串s从下标2开始到结束的部分
    s.substr(2,5);  //取字符串s从下标2开始长度为5的部分

△ 字符串拼接

    s = s + 'a';
    s = s + "hello";
    s += "hello";
    s = "hello" + "world";//注意,这种写法是错的(想一想为什么?)

getline(); // 读入一行,用法:

    getline(cin, s);

△ 字典序 联系英语词典单词的排序方式,如果你能够轻松的对这几个字符串按字典序排序,那么可以断定你已经理解了:

    abs
    ab
    abc
    abcde

△ 字典序比较:string类型的字符串也可用下面比较符

    >
    <
    ==
    >=
    <=
    !=

下面是一些字符串的习题:


字符串中A的数量

Description

输入一个字符串,统计其中字符 A 的数量并且输出。

Input

输入共有一行,为一个不带空格的字符串(其中字符数不超过 100)。

Output

输出一行,包含一个整数, 为输入字符串中的 A 的数量。

这题只需要用size()函数得到字符串的长度,然后用for循环一个字符一个字符地访问看是不是'A’就可以了:

#include<iostream>
#include<cstring>//有关字符串的操作都需要加上cstring的头文件
using namespace std;

int main(){
	string s;
	cin >> s;
	
	int cnt = 0;//记录'A'出现的次数
	for(int i = 0; i < s.size(); i++){
		if(s[i] == 'A'){
			cnt++;
		}
	}
	
	cout << cnt;
	return 0;
}

*这里需要注意的是,字符串的下标是从0开始,到字符串长度减一结束的。

当然了,使用find()函数也是可以做的,但是对下标的控制需要熟练:

#include<iostream>
#include<cstring>
using namespace std;

int main(){
	string s;
	cin >> s;
	
	int cnt = 0;
	int d = -1;//存储下标的值
	do{
		d = s.find('A', d + 1);
		if(d != -1) cnt++;
	}while(d != -1);
	
	cout << cnt;
	return 0;
}

下一个字母

Description

从键盘输入一个长度大于 10 的字符串,现要求:将字符串中的所有大小写字母都改写成该字母的下一个字母;特殊的,小写字母 z 改写成字母 a;大写字母 Z 改写成 A,其他字符依照原有顺序不变。

Input

输入只有一行,包含 1 个任意的不带有空格的字符串(其长度在 10 到 1000 之间)。

Output

输出只有一行,即为满足条件的字符串。

对于字符,是可以当做整数来进行运算的(具体参照ASCII码)。这题需要对'Z'和‘z’进行特殊判断一下。代码如下:

#include<iostream>
#include<cstring>
using namespace std;

int main(){
  string str;
  cin >> str;
  
  int len = str.size();
  for(int i = 0; i < len; i++){
    if((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z') ){
      str[i]++;
      if(str[i] > 'Z' && str[i] < 'a') str[i] = 'A';
      else if(str[i] > 'z') str[i] = 'a';
	}
  }
  
  cout << str << endl;
  return 0;
}

选小寿星

Description

五年级一班有一个传统,全班一起庆祝当月过生日的同学。有 m 名学生都是 1 月份过生日,班主任决定挑一名学生作为寿星代表切蛋糕。班主任将过生日的 m 名学生随机围成一个圈,从 1 到 m 进行编号。随机挑一个数字 n(1≤n≤9),从第一个同学开始连续报数,报数到 n 的同学就出局,然后从下一位 同学重新开始报数,一直到剩下最后一名同学。由于女生少,班主任决定每个女生有 2 次机会,也就是说,每名女生第 2 次数到 n 时才出局。

例如,m=3,其中有 1 名女生,编号顺序为 1,2,3,分别是男,女,男,n=2。第一轮报数,报到的是 2 号女生,暂不出局(注:女生有 2 次机会)。第二轮报数,3 号男生报 1,1 号男生报 2 出局。第三轮报数,2 号女生报 1,3 号男生报 2 出局,最后留下 2 号女生。

Input

输入第一行输入数字为 m,表示有 m 个人,m<20。

第二行是 m 个整数,1 代表男生,0 代表女生。

第三行是 n,表示 n 是出局数字。(注意:女生有 2 次机会)

Output

输出留下学生的序号,中间用空格隔开。

这题就比较经典了。这题需要将出局的学生进行标记,直到只有一个人未被标记时,游戏结束。

#include<iostream>
using namespace std;

const int maxn = 10000 + 5;
bool sex[maxn];//记录学生的性别,0为女生、1为男生

int main(){
  int m; cin >> m;
  for (int i = 1 ; i <= m ; i++) cin >> sex[i];
  int n; cin >> n;
  
  int stu[maxn];
  for (int i = 1 ; i <= m ; i++) {
  	if (sex[i] == 0) stu[i] = 2 ;//女生两次机会
  	else stu[i] = 1;//男生一次机会
  }
  
  int t = 0 ;
  int chance = 0 ;//记录总共的机会数
  for(int i = 1 ; i <= m ; i++) chance += stu[i] ;
  
  for (int i = 1 ; ; i++) {
  	if(chance == 1) break ;//当总机会数只剩下1时,不论剩下男生还是女生,游戏都将结束
    if(i == m+1) i = 1 ;//将队伍的首位连接起来
  	if(stu[i] == 0) continue ;//如果轮到的人已经出局,不进行下面的操作,进行下一次循环
  	t++ ;//报数
  	if(t == n){
  	  t = 0 ;
  	  stu[i]-- ;
  	  chance-- ;
	}//报到n的人减少一次机会,总机会数也减一,报出的数归零。
  }
  
  int temp = 0 ;
  for(int i = 1 ; i <= m ; i++){
  	if(stu[i] != 0) cout << i ;//寻找未出局的人
  }
  return 0 ;
}

这里是考察对数据的操控。


规范化名字

Description

一个 名单里面有大型机械的很多零部件名,但是由于制作这个名单的人习惯不太好,零部件的名称的大小写很混乱。有的是大写字母开头,有些是小写字母开头,零部件名称中间的字符也是大小写混乱。

请你设计程序,将名单上零部件的名称都变为开头字母大写,后面字母全小写的形式。

Input

输入第一行只有一个正整数 N,表示名单上的零部件(1≤N≤100)。

之后的 N 行: 为 N 个零部件的名称。

Output

输出为 N 行,为所有 N 个零部件的名称, 首字母为大写,后面 的字母为小写。

这里要用到c++中的两个函数:toupper(),tolower(),它们的作用分别是将字母转大写、转小写。代码如下:

#include<iostream>
#include<cstring>
using namespace std;

int main(){
  int n; cin >> n;
  string name[n + 1];
  for(int i = 1; i <= n; i++) cin >> name[i];
  
  int len[n + 1];
  for(int i = 1; i <= n; i++){
  	len[i] = name[i].size();
  }
  
  for(int i = 1; i <= n; i++){
  	for(int j = 0; j < len[i]; j++){
  	  if(j == 0) name[i][j] = toupper(name[i][j]);
  	  else name[i][j] = tolower(name[i][j]);
	}
  }
  
  for(int i = 1; i <= n; i++){
  	cout << name[i] << endl;
  }
  return 0;
}

禁止吸烟

Description

小信的学校设计了很多的标语,但是中间很多地方都把 No_smoking 写成了 Ban_smoking。请你找到这些错误并将他们替换成正确的结果。

Input

输入第一行为 N 表示总共的标语数量。

之后的 N 行每行是一个待处理的标语。每个标语中不带有任何的空格。

Output

输出为 N 行, 为经过处理后的所有的标语。输出顺序与输入时保持 一致。

这题只要灵活使用find()、replace()就可以了。代码如下:

#include<iostream>
#include<cstring>
using namespace std;

const int maxn = 10000+5;
const string wstr = "Ban_smoking", re = "No_smoking";
const int lenws = 11;//"Ban_smoking"的长度

int main(){
  int n;
  cin >> n;
  
  string sign[maxn];
  for(int i = 1; i <= n; i++) cin >> sign[i];
  
  for(int i = 1; i <= n; i++){
  	int beg;
  	beg = sign[i].find(wstr);
  	while(beg != -1){
  	  sign[i].replace(beg, lenws, re);
  	  beg = sign[i].find(wstr);
	}
	cout << sign[i] << endl;
  }
  return 0;
}

 

展开阅读全文

没有更多推荐了,返回首页