字符串的应用¶
下面处理英文字母、数字和常见符号,字符串长度能放进 int。代码片段分别使用,需要 <iostream>、<string> 和 using namespace std;。
读入一整行¶
cin >> s 遇到空白就停;要读入一整行,包括空格,用 getline。
getline 读走换行,但不把换行存进 s;读到空行,s 就是空串。
和 cin >> 混用,注意残留的换行。 第一行输入 n 后直接换行,第二行输入句子,可以这样写:
getchar() 读走一个字符,这里读走换行,需要 <cstdio>。
n 后面别留空格,否则读走的是空格。
不处理换行,getline 可能读到空串,看起来像“没有输入就结束了”。
统计字符¶
输入一个由大小写字母、数字组成的字符串,分别统计每个字符出现的次数。
string s;
cin >> s;
for (char c : s) {
if (c >= 'A' && c <= 'Z') cntA[c - 'A']++;
else if (c >= 'a' && c <= 'z') cnta[c - 'a']++;
else if (c >= '0' && c <= '9') cnt[c - '0']++;
}
'A' 减去 'A' 得到 0,'B' 减去 'A' 得到 1,正好对应计数数组的下标。
统计完以后,按题目要求输出。比如输出 26 个大写字母的次数:
大小写转换¶
把大写字母转成小写,其他字符保持原样。
string s;
getline(cin, s);
int len = (int)s.size();
for (int i = 0; i < len; i++)
if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 'a' - 'A';
cout << s;
'a' - 'A' 是大小写字母的编码差值。
补充:范围循环修改字符,用 char &c。 学过引用后再看。
char &c 能修改原字符;char c 改的是副本,s 不变。
过滤空格¶
直接输出过滤后的内容
存进一个新字符串
这里只去掉普通空格 ' ',不是删除所有空白字符。
抠单词操作(重点)¶
按空格、逗号抠出单词,打擂台,找第一个最长单词和第一个最短单词。保证至少有一个单词。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
getline(cin, s);
int len = (int)s.size();
int i = 0, maxn = -1, minn = len + 1;
string maxt, mint;
while (i < len) {
if (s[i] == ' ' || s[i] == ',') {
i++;
continue;
}
string t;
while (i < len && s[i] != ' ' && s[i] != ',') t += s[i++];
int cnt = (int)t.size();
if (cnt > maxn) {
maxn = cnt;
maxt = t;
}
if (cnt < minn) {
minn = cnt;
mint = t;
}
}
cout << maxt << '\n' << mint;
return 0;
}
跳过分隔符。 遇到空格、逗号,i 往后走,连续多个也要跳过。
取出一个单词。 用 while 收集字符,碰到分隔符或行尾就停;i < len 写在访问 s[i] 前面。
更新最长、最短单词。 用 >、<,不加等号,并列时保留第一个。
截取子串¶
从字符串中取出一段,用 substr。
substr 得到一个新字符串,不会改变原来的 s。起点不能超过 s.size()。
翻转字符串¶
把 abc 翻转成 cba,可以用 reverse,需要 <algorithm>。
查找后,逐个替换¶
查找子串、字符
string s = "zqoizq";
cout << s.find("zq"); // 第一次出现的位置,0
cout << s.find('q'); // 第一次出现的位置,1
cout << s.find("zq", 2); // 从下标2往后找,得到4
没找到,返回 string::npos。
不要把 find 的结果直接当条件:位置 0 也可能是找到,而 npos 也不是 0。
替换子串
逐个替换
把句子里的 cat 逐个替换成 dog。这里按字符查找,不判断单词边界。
string s = "cat cat";
auto p = s.find("cat");
while (p != string::npos) {
s.replace(p, 3, "dog");
p = s.find("cat", p + 3);
}
cout << s; // 输出dog dog
auto 自动确定 p 的类型,string::npos 表示没找到。
替换完,继续往后找。 dog 长度为 3,所以下次从 p + 3 开始。
别反复查找刚替换的位置;新内容包含原查找串时,可能停不下来。
统计单词(先不看)¶
统计单词出现次数,可以用 map,需要 <map>。学过 STL 后再看。
int n;
cin >> n;
map<string, int> mp;
string s;
while (n--) {
cin >> s;
mp[s]++;
}
for (auto p : mp) cout << p.first << ' ' << p.second << '\n';
mp[s] 记录单词 s 的次数,新单词从 0 开始计数。
first 是单词,second 是次数,按单词的字典序输出。