1. 题目背景与需求解析
这道编程题来自GESP(青少年编程能力等级考试)2026年3月C++一级认证的第三部分。题目要求考生编写一个简单的"交朋友"程序,主要考察基础的输入输出、条件判断和字符串处理能力。作为入门级认证的编程题,它很好地体现了计算机编程解决实际问题的思维方式。
题目通常会给出类似这样的场景描述:假设你正在开发一个社交程序,需要根据用户输入的信息判断是否可以成为朋友。程序需要接收用户输入的年龄和爱好,如果年龄相差不超过5岁且有至少一个共同爱好,则输出"可以成为朋友",否则输出"暂时不能成为朋友"。
2. 核心解题思路分析
2.1 输入输出设计
首先需要明确程序的输入输出要求。典型的输入格式可能是:
- 第一行输入第一个人的年龄和爱好(爱好之间用空格分隔)
- 第二行输入第二个人的年龄和爱好
例如:
code复制18 篮球 音乐 游戏
20 音乐 电影 阅读
输出则是一个简单的判断结果字符串。
2.2 关键算法逻辑
解决这个问题的核心算法可以分为三个步骤:
- 年龄差计算:获取两个用户的年龄,计算绝对差值
- 爱好比对:遍历两个爱好列表,查找是否存在交集
- 结果判断:结合年龄差和爱好比对结果输出最终结论
2.3 数据结构选择
对于C++一级考试而言,最合适的数据结构是:
- 使用
int存储年龄 - 使用
vector<string>或数组存储爱好列表 - 使用
string存储输出结果
3. 完整代码实现与解析
3.1 基础框架搭建
首先构建程序的基本框架:
cpp复制#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // 用于find函数
using namespace std;
int main() {
// 变量声明
int age1, age2;
vector<string> hobbies1, hobbies2;
// 输入处理
// ...(后续补充)
// 业务逻辑
// ...(后续补充)
// 输出结果
// ...(后续补充)
return 0;
}
3.2 输入处理实现
处理输入是本题的第一个关键点。我们需要正确读取年龄和不定数量的爱好:
cpp复制// 读取第一个人的信息
cin >> age1;
string hobby;
while (cin >> hobby) {
hobbies1.push_back(hobby);
if (cin.peek() == '\n') break; // 遇到换行符停止
}
// 清空输入缓冲区
cin.ignore();
// 读取第二个人的信息
cin >> age2;
while (cin >> hobby) {
hobbies2.push_back(hobby);
if (cin.peek() == '\n') break;
}
注意:这里使用
cin.peek()检查下一个字符是否是换行符,这是处理不定数量输入的关键技巧。
3.3 年龄差判断
年龄判断相对简单,计算绝对差值即可:
cpp复制bool ageMatch = abs(age1 - age2) <= 5;
3.4 共同爱好检测
查找共同爱好的算法有多种实现方式,这里展示两种常见方法:
方法一:嵌套循环查找
cpp复制bool hasCommonHobby = false;
for (const auto& h1 : hobbies1) {
for (const auto& h2 : hobbies2) {
if (h1 == h2) {
hasCommonHobby = true;
break;
}
}
if (hasCommonHobby) break;
}
方法二:使用STL算法
cpp复制bool hasCommonHobby = false;
for (const auto& h : hobbies1) {
if (find(hobbies2.begin(), hobbies2.end(), h) != hobbies2.end()) {
hasCommonHobby = true;
break;
}
}
3.5 结果判断与输出
最后根据两个条件判断并输出结果:
cpp复制if (ageMatch && hasCommonHobby) {
cout << "可以成为朋友" << endl;
} else {
cout << "暂时不能成为朋友" << endl;
}
4. 完整代码示例
将上述各部分组合起来,得到完整解决方案:
cpp复制#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
// 变量声明
int age1, age2;
vector<string> hobbies1, hobbies2;
// 输入处理
cin >> age1;
string hobby;
while (cin >> hobby) {
hobbies1.push_back(hobby);
if (cin.peek() == '\n') break;
}
cin.ignore();
cin >> age2;
while (cin >> hobby) {
hobbies2.push_back(hobby);
if (cin.peek() == '\n') break;
}
// 年龄判断
bool ageMatch = abs(age1 - age2) <= 5;
// 共同爱好判断
bool hasCommonHobby = false;
for (const auto& h : hobbies1) {
if (find(hobbies2.begin(), hobbies2.end(), h) != hobbies2.end()) {
hasCommonHobby = true;
break;
}
}
// 结果输出
if (ageMatch && hasCommonHobby) {
cout << "可以成为朋友" << endl;
} else {
cout << "暂时不能成为朋友" << endl;
}
return 0;
}
5. 测试用例与验证
为确保程序正确性,需要设计多种测试场景:
5.1 正常情况测试
测试用例1:年龄相近且有共同爱好
code复制18 篮球 音乐
20 音乐 电影
预期输出:可以成为朋友
测试用例2:年龄相差大但有很多共同爱好
code复制15 游泳 读书
25 游泳 读书
预期输出:暂时不能成为朋友
5.2 边界情况测试
测试用例3:年龄差刚好5岁
code复制20 篮球
25 篮球
预期输出:可以成为朋友
测试用例4:年龄差6岁
code复制20 篮球
26 篮球
预期输出:暂时不能成为朋友
5.3 特殊输入测试
测试用例5:没有共同爱好
code复制18 篮球
18 足球
预期输出:暂时不能成为朋友
测试用例6:一个爱好很多,一个爱好很少
code复制30 音乐 电影 游戏 运动 烹饪
28 烹饪
预期输出:可以成为朋友
6. 常见问题与优化建议
6.1 常见错误分析
-
输入处理不完整:忘记处理换行符导致第二个人的信息读取错误
- 解决方法:使用
cin.peek()检查换行符或使用cin.ignore()
- 解决方法:使用
-
年龄差计算错误:忘记取绝对值
- 错误示例:
if (age1 - age2 <= 5) - 正确写法:
if (abs(age1 - age2) <= 5)
- 错误示例:
-
爱好比较不准确:大小写敏感导致匹配失败
- 建议:将所有爱好转为统一大小写再比较
6.2 代码优化方向
- 提取函数提高可读性:
cpp复制bool checkAgeMatch(int a1, int a2, int maxDiff) {
return abs(a1 - a2) <= maxDiff;
}
bool checkCommonHobby(const vector<string>& h1, const vector<string>& h2) {
// ...实现代码...
}
-
使用更高效的查找算法:可以先对爱好排序,再用二分查找
-
增加输入验证:检查年龄是否为有效正整数
6.3 扩展思考
如果题目要求升级,可以考虑:
- 输出具体的共同爱好是什么
- 支持模糊匹配爱好(如"篮球"和"打篮球"视为相同)
- 考虑更多交友因素(如性别、地理位置等)
7. 学习价值与总结
这道题目虽然简单,但涵盖了编程入门阶段的多个核心知识点:
- 基础语法:变量声明、输入输出、条件判断
- 数据结构:数组/向量的使用
- 算法思维:遍历查找、条件组合
- 实际问题解决:将生活场景转化为程序逻辑
对于初学者来说,建议重点掌握:
- 如何正确处理不定数量的输入
- 使用合适的数据结构存储信息
- 设计清晰的判断逻辑流程
- 编写可读性好的代码
在实际编程中,我通常会先画出流程图明确逻辑,再着手编写代码。测试时要特别注意边界情况,比如年龄差刚好5岁的情况。另外,良好的代码习惯如合理注释、变量命名规范等,对于长期编程能力的培养至关重要。