文章目录
1 字符与整数的联系——ASCII码
每个常用字符都对应一个-128~127的数字,二者之间可以相互转化:
常用ASCII值:’A’-‘Z’ 是65~90,’a’-‘z’是97-122,’0’-‘9’是48-57。字符可以参与运算,运算时会将其当做整数:
练习:输入一行字符,统计出其中数字字符的个数,以及字母字符的个数。
2 字符数组
字符串就是字符数组加上结束符’\0’。
可以使用字符串来初始化字符数组,但此时要注意,每个字符串结尾会暗含一个’\0’字符,因此字符数组的长度至少要比字符串的长度多1!
2.1 字符数组的输入输出
2.1.1 输入操作
无空格的字符数组 cin
一个问题
输入:safaf dds
读入的是safaf,遇到空格、回车等字符就停止输入了
有空格的字符数组 fgets(stdio) cin.getline(iostream)
读到字符数组中:
fgets
cin.getline(s,100);
char str[31];
scanf("%s", str);
从字符数组下标1开始读入
2.1.2 输出操作 printf puts cout
char s[1000];
printf("%s\n",s);
puts(s);//puts(char *)
2.2 字符数组的常用操作
下面几个函数需要引入头文件:
#include <string.h>
(1) strlen(str),(string length)求字符串的长度,不包含\0
(2) strcmp(a, b),(string compare)比较两个字符串的大小,a < b 返回-1,a == b 返回0,a > b返回1。这里的比较方式是字典序!
(3) strcpy(a, b),(string copy)将字符串b复制给从a开始的字符数组。
注意:strlen求长度实际上是一层for循环,直接用来i < strlen(s),这样每次判断都要执行循环,效率很低,事先先存起来
2.3 练习
760. 字符串长度
给定一行长度不超过 100 的字符串,请你求出它的具体长度。
输入格式
输入一行,表示一个字符串。注意字符串中可能包含空格。
输出格式
输出一个整数,表示它的长度。
输入样例:
I love Beijing.
输出样例:
15
#include <iostream>
using namespace std;
int main()
{
char chs[101];// 注意不能是char chs[100], 还要多一位存储\0
cin.getline(chs, 101);// fgets(chs, 101, stdin);
int i;
for(i = 0; chs[i] && chs[i] != '\n'; i++);
cout<<i<<endl;
return 0;
}
772. 只出现一次的字符
给你一个只包含小写字母的字符串。
请你判断是否存在只在字符串中出现过一次的字符。
如果存在,则输出满足条件的字符中位置最靠前的那个。
如果没有,输出 no。
输入格式
共一行,包含一个由小写字母构成的字符串。
数据保证字符串的长度不超过 100000。
输出格式
输出满足条件的第一个字符。
如果没有,则输出 no。
输入样例:
abceabcd
输出样例:
e
#include <iostream>
#include <cstring>
using namespace std;
//堆中没有限制大小,且已经默认初始化0
char s[1000000];
//每个字母的次数,下标字母,'a' -'a', 即下标0存储的是a字母的次数,0-25,对应'a'到'z'
int cnt[26];
int main()
{
cin>>s;
for(int i = 0, len = strlen(s); i < len; i++){
cnt[s[i] - 'a']++;
}
for(int i = 0, len = strlen(s); i < len; i++){
if(cnt[s[i] - 'a'] == 1){
cout<<s[i]<<endl;
return 0;
}
}
cout<<"no"<<endl;
return 0;
}
3 字符串
标准库类型 string
可变长的字符序列,比字符数组更加好用。需要引入头文件:
#include <string>
3.1 定义和初始化
3.2 string 的输入输出
无空格的输入cin
有空格的输入getline
使用getline读取一整行
不能直接用printf输出,可用cout
注意:不能用printf直接输出string,需要写成:printf(“%s”, s.c_str()); s.c_str()返回字符数组的首地址
3.3 string的一些操作
(3) string的empty和size操作(注意size是无符号整数,因此 s.size() <= -1一定成立):
string里的size不同于strlen,是O(1)的,会使用数存储长度
(4) string 的比较:
支持 > < >= <= == !=等所有比较操作,按字典序进行比较。不同于字符数组需要strcmp
(5) 为string对象赋值:
string s1(10, ‘c’), s2; // s1的内容是 cccccccccc;s2是一个空字符串
s1 = s2; // 赋值:用s2的副本替换s1的副本
// 此时s1和s2都是空字符串
(6) 两个string对象相加:
string s1 = “hello, ”, s2 = “world\n”;
string s3 = s1 + s2; // s3的内容是 hello, world\n
s1 += s2; // s1 = s1 + s2
(7) 字面值和string对象相加:
做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来:
string s1 = “hello”, s2 = “world”; // 在s1和s2中都没有标点符号
string s3 = s1 + “, “ + s2 + ‘\n’;
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + “, “; // 正确:把一个string对象和有一个字面值相加
string s5 = “hello” +”, “; // 错误:两个运算对象都不是string
string s6 = s1 + “, “ + “world”; // 正确,每个加法运算都有一个运算符是string
string s7 = “hello” + “, “ + s2; // 错误:不能把字面值直接相加,运算是从左到右进行的
(8)string.pop_back()
把最后一个字符删掉,如删除字符串末尾空字符
参数:无
返回值:无
(9) string.substr()
substr有2种用法:
假设:string s = “0123456789”;
string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = “56789”
string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = “567”
3.4 遍历string对象
可以将string对象当成字符数组来处理:
或者使用基于范围的for语句:
3.5 练习
练习:密码翻译,输入一个只包含小写字母的字符串,将其中的每个字母替换成它的后继字母,如果原字母是’z’,则替换成’a’。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin,s);
for(auto &ch : s){
//auto指定由系统判断ch的类型, 必须是ch的引用才可以对字符串中的字符修改生效
if(ch >= 'a' && ch <= 'z')
{
//(ch - 'a' + 1)%26 求出加密后该字符在26个字母中的位次
ch = 'a' + (ch - 'a' + 1)%26;
}
else if(ch >= 'A' && ch <= 'Z')
{
ch = 'A' + (ch - 'A' + 1)%26;
}
}
cout<<s<<endl;
return 0;
}
练习:输入两个字符串,验证其中一个串是否为另一个串的子串。
- 循环相克令
猜拳游戏
循环相克令是一个两人玩的小游戏。
令词为“猎人、狗熊、枪”,两人同时说出令词,猎人赢枪、枪赢狗熊、狗熊赢猎人,动作相同则视为平局。
现在给定你一系列的组合,请你判断游戏结果。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
接下来 T 行,每行包含两个字符串,表示一局游戏中两人做出的动作,字符串为 Hunter, Bear, Gun 中的一个,
这三个单词分别代表猎人,狗熊和枪。
输出格式
如果第一个玩家赢了,则输出 Player1。
如果第二个玩家赢了,则输出 Player2。
如果平局,则输出 Tie。
数据范围
1≤N≤100
输入样例
3
Hunter Gun
Bear Bear
Hunter Bear
输出样例
Player1
Tie
Player2
#include <iostream>
#include <string>
using namespace std;
int main()
{
int t;
cin>>t;
while(t > 0)
{
t--;
string str1;
string str2;
cin>>str1>>str2;
int x; //x表示玩家1
int y; //y表示玩家2
//用0、1、2标注玩家x和y出的是狗、猎人还是抢
if(str1 == "Hunter") x = 0;
else if(str1 == "Gun") x = 1;
else if(str1 == "Bear") x = 2;
if(str2 == "Hunter") y = 0;
else if(str2 == "Gun") y = 1;
else if(str2 == "Bear") y = 2;
if(x == y) puts("Tie");
else if(x == (y+2)%3 ) puts("Player1");
else puts("Player2");
}
return 0;
}