题解
2026-02-26 12:40:43
发布于:浙江
23阅读
0回复
0点赞
题目解析
- 输入输出:输入为一行字符串,包含若干待检测密码,各密码间以英文逗号
,分隔(单个密码内部不含空格和逗号)。需按输入顺序,每行输出一组合规的密码;不合规的密码不输出。 - 数据范围:输入总行长不超过 ,单密码长度在题目要求外无其他限制(但代码中通过长度检查过滤)。
- 复杂度要求:字符串长度极小,( 为输入总长)的线性扫描即可满足 时限。
- 算法知识点:
字符串处理、模拟验证、字符串分割、字符分类统计
思路解析
- 字符串分割:由于输入将多个密码用逗号连接成一行,需将其拆分为独立密码串处理。利用
string::find(',')定位分隔符,提取子串后,使用erase删除已处理部分(包括逗号),循环直至字符串为空。 - 多条件验证(check函数):
- 长度筛选:首先检查长度是否在 区间内,不满足直接返回
false。 - 字符集过滤:遍历密码每个字符,若出现非大小写字母、非数字、且非
!@#$的字符,立即判定不合规。 - 类型统计:维护四个计数器:
upper_cnt:大写字母是否存在(标记型,最多为1)lower_cnt:小写字母是否存在(标记型,最多为1)number_cnt:数字是否存在(标记型,最多为1)special_cnt:特殊字符!@#$的累计数量(题目要求至少1个)
- 组合条件判定:检查
(upper_cnt + lower_cnt + number_cnt) >= 2(字母数字类至少两种)且special_cnt > 0(至少一个特殊字符),均满足返回true。
- 长度筛选:首先检查长度是否在 区间内,不满足直接返回
- 输出控制:主循环中,仅当
check(temp)返回真时,输出该密码子串。
完整代码
#include <bits/stdc++.h>
using namespace std;
// 验证单条密码是否合规
bool check(string s) {
// 条件2:长度必须在6-12之间
if (s.size() < 6 or s.size() > 12) return false;
int upper_cnt = 0, lower_cnt = 0, number_cnt = 0, special_cnt = 0;
for (int i = 0; i < s.size(); i++) {
// 条件1:字符集检查,只能包含大小写字母、数字、!@#$
if (!(isupper(s[i]) || islower(s[i]) || isdigit(s[i])
|| s[i] == '@' || s[i] == '#' || s[i] == '$' || s[i] == '!'))
return false;
// 统计各类字符存在性(大写、小写、数字只需标记存在,故用==0判断避免重复计数)
if (isupper(s[i]) && upper_cnt == 0) upper_cnt++;
else if (islower(s[i]) && lower_cnt == 0) lower_cnt++;
else if (isdigit(s[i]) && number_cnt == 0) number_cnt++;
// 特殊字符统计具体数量(题目要求至少1个)
else if (s[i] == '@' || s[i] == '#' || s[i] == '$' || s[i] == '!')
special_cnt++;
}
// 条件3:字母数字类至少两种,且至少一个特殊字符
if (upper_cnt + lower_cnt + number_cnt < 2 || special_cnt == 0)
return false;
else
return true;
}
int main() {
string s;
cin >> s;
// 循环处理,直到字符串被分割完毕
while (!s.empty()) {
int idx = s.find(','); // 查找下一个逗号分隔符
if (idx == -1) idx = s.size(); // 无逗号则处理剩余全部
// 提取当前密码子串 [0, idx)
string temp = s.substr(0, idx); // 注:原代码用循环拼接,此处等价
if (check(temp)) cout << temp << endl; // 合规则输出
s.erase(0, idx + 1); // 删除已处理部分及分隔逗号
}
return 0;
}
这里空空如也

有帮助,赞一个