[特殊字符] 2025蓝桥杯备赛Day10——B2120 单词的长度
🔍 2025蓝桥杯备赛Day10——B2120 单词的长度
🚀 题目速览
题目难度:⭐️ 适合掌握字符串基本操作
考察重点:字符串分割、空格处理、标点符号处理
B2120 单词的长度
题目描述
输入一行单词序列,相邻单词之间由 1 1 1 个或多个空格间隔,请对应地计算各个单词的长度。
注意:如果有标点符号(如连字符,逗号),标点符号算作与之相连的词的一部分。没有被空格间开的符号串,都算作单词。
输入格式
一行单词序列,最少 1 1 1 个单词,最多 300 300 300 个单词,单词之间用至少 1 1 1 个空格间隔。单词序列总长度不超过 1000 1000 1000。
输出格式
依次输出对应单词的长度,之间以逗号间隔。
输入输出样例 #1
输入 #1
She was born in 1990-01-02 and from Beijing city.
输出 #1
3,3,4,2,10,3,4,7,5
🔥 解法一:基于split函数(推荐)
🛠️ 实现思路
核心技巧:利用split()
函数分割单词,忽略多余空格
算法优势:代码简洁,时间复杂度 O(n)
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string input;
getline(cin, input); // 读取整行输入
stringstream ss(input); // 使用字符串流分割单词
string word;
vector<int> lengths;
while (ss >> word) { // 自动处理多余空格
lengths.push_back(word.size());
}
// 输出结果
for (int i = 0; i < lengths.size(); ++i) {
if (i > 0) cout << ",";
cout << lengths[i];
}
return 0;
}
🔥 解法二:手动遍历法(底层实现)
🛠️ 实现思路
核心技巧:逐个字符遍历,记录单词长度
教学价值:理解字符串处理的底层逻辑
#include <iostream>
#include <vector>
using namespace std;
int main() {
string input;
getline(cin, input);
vector<int> lengths;
int count = 0;
for (char c : input) {
if (c != ' ') {
++count; // 非空格字符计入单词长度
} else if (count > 0) { // 遇到空格且当前单词长度 > 0
lengths.push_back(count);
count = 0; // 重置计数器
}
}
// 处理最后一个单词
if (count > 0) lengths.push_back(count);
// 输出结果
for (int i = 0; i < lengths.size(); ++i) {
if (i > 0) cout << ",";
cout << lengths[i];
}
return 0;
}
🔥 解法三:极简流处理法(竞赛最优解)
🛠️ 实现思路
核心机制:利用cin >>
自动跳过多余空格的特性
核心优势:零额外内存消耗,时间复杂度 O(n),代码量最少(仅10行)
#include <iostream>
using namespace std;
int main() {
string s;
bool flag = true; // 首单词标记
while (cin >> s) { // cin自动处理所有空格
if (flag) { // 首单词无前导逗号
cout << s.size();
flag = false;
} else {
cout << ',' << s.size(); // 后续单词添加逗号
}
}
return 0;
}
📚 知识点总结
一、关键库函数
-
stringstream
stringstream ss(input); // 将字符串转为流 ss >> word; // 自动分割单词(忽略多余空格)
-
getline()
getline(cin, input); // 读取整行输入(兼容含空格的字符串)
-
size()/length()
int len = word.size(); // 获取字符串长度
二、手动遍历技巧
-
边界处理
- 连续多个空格:跳过空单词
- 最后一个单词:遍历结束后需单独处理
-
字符判断
if (c != ' ') { ... } // 非空格字符计入单词长度
🔥 解法对比分析
维度 | 基于split函数(解法一) | 手动遍历法(解法二) | 极简流处理法(解法三) |
---|---|---|---|
时间复杂度 | O(n) | O(n) | O(n) |
扩展性 | ★★★★☆(函数可扩展) | ★★☆☆☆(需改逻辑) | ★☆☆☆☆(固定流程) |
可读性 | ★★★★★(逻辑分层) | ★★★☆☆(细节复杂) | ★★★★★(极简直观) |
内存占用 | O(1) | O(1) | O(1) |
抗错能力 | ★★★★☆(自动过滤空格) | ★★☆☆☆(需处理边界) | ★★★★☆(题目保证合法) |
代码量 | 15行 | 18行 | 10行 |
🚨 常见错误警示
错误1:未处理连续空格
// 错误:直接使用cin分割单词
cin >> word; // 无法处理多余空格
// 修正:使用getline+stringstream
错误2:遗漏最后一个单词
// 错误:遍历结束后未处理最后一个单词
if (count > 0) lengths.push_back(count); // 必须添加
错误3:输出格式错误
// 错误:末尾多出逗号
cout << lengths[i] << ","; // 应判断是否为最后一个单词
// 修正:在循环中判断i > 0时输出逗号
🌟 举一反三
变种题1:统计单词频次
unordered_map<string, int> freq;
while (ss >> word) {
++freq[word]; // 统计单词出现次数
}
变种题2:单词逆序输出
vector<string> words;
while (ss >> word) words.push_back(word);
reverse(words.begin(), words.end()); // 逆序输出单词
蓝桥杯考场策略:
- 优先使用解法一:代码简洁,执行高效
- 必测用例:
- 连续多个空格:
"a b c"
→1,1,1
- 含标点符号:
"hello,world!"
→11
- 单个单词:
"abc"
→3
- 连续多个空格: