本题要求我们对输入的多个密码进行合规性检测。输入是一个用英文逗号分隔的字符串,每一段代表一个待检测的密码。合规的密码必须同时满足以下条件:
a~z、大写字母 A~Z、数字 0~9 以及四个特殊字符 !@#$ 组成。!@#$ 中的任意一个)。我们需要按输入顺序输出所有合规的密码,每行一个。
由于输入由逗号分隔多个密码,我们可以这样做:
整个流程主要分为两个部分:字符串分割 和 密码检查。
采用遍历输入字符串,维护一个缓冲数组 pwd 和当前密码长度 len。
pwd 并让 len 加一。pwd 末尾添加字符串结束符 \0,然后调用检查函数。清空 len 为 0,准备接收下一段密码。len > 0,说明最后还有一段密码没有处理(结尾没有逗号),同样进行合规检查。定义一个函数 check(char *str, int l):
l < 6 或 l > 12,直接返回不合法。hasC(有大写)、hasL(有小写)、hasD(有数字)、hasS(有特殊字符),初始均为 false。hasC = truehasL = truehasD = true!@#$ 之一 → hasS = truehasS:如果没有特殊字符,返回不合法。hasC + hasL + hasD,必须 ≥ 2,否则返回不合法。因为密码长度很短(最长12),直接逐字符检查是最清晰、最高效的方法。使用布尔标记可以轻松统计出现的字符类型。注意特殊字符只有四个,而不是任意标点符号,判断时要精确到这四个字符。
设输入字符串总长度为 N(题目约定不超过 100)。我们只对输入进行了一次遍历,并在每个密码内部逐字符检查。每个字符最多被访问常数次,因此总时间复杂度为 O(N),可以轻松通过本题。
cpp1#include <iostream> 2using namespace std; 3 4char line[101]; // 存放输入的整行字符串 5char pwd[101]; // 暂存当前正在处理的密码 6 7// 检查从 str 开始、长度为 l 的密码是否合规 8bool check(char *str, int l) { 9 // 1. 长度检查 10 if (l < 6 || l > 12) 11 return false; 12 13 bool hasC = false, hasL = false, hasD = false, hasS = false; 14 // 2. 遍历字符进行分类统计 15 for (int i = 0; str[i] != '\0'; i++) { 16 if ('A' <= str[i] && str[i] <= 'Z') { 17 hasC = true; 18 } else if ('a' <= str[i] && str[i] <= 'z') { 19 hasL = true; 20 } else if ('0' <= str[i] && str[i] <= '9') { 21 hasD = true; 22 } else if (str[i] == '!' || str[i] == '@' || 23 str[i] == '#' || str[i] == '$') { 24 hasS = true; 25 } else { 26 // 出现了非法字符 27 return false; 28 } 29 } 30 31 // 3. 至少一个特殊字符 32 if (!hasS) 33 return false; 34 // 4. 大写、小写、数字至少有两种 35 if (hasC + hasL + hasD < 2) 36 return false; 37 38 return true; 39} 40 41int main() { 42 cin >> line; 43 44 int len = 0; // 当前密码的长度 45 for (int i = 0; line[i] != '\0'; i++) { 46 if (line[i] != ',') { 47 pwd[len] = line[i]; 48 len++; 49 } else { 50 pwd[len] = '\0'; // 字符串结束符 51 if (check(pwd, len)) 52 cout << pwd << endl; 53 len = 0; // 重置长度,准备下一段 54 } 55 } 56 57 // 处理最后一段密码(结尾没有逗号的情况) 58 if (len > 0) { 59 pwd[len] = '\0'; 60 if (check(pwd, len)) 61 cout << pwd << endl; 62 } 63 64 return 0; 65}
line 数组存储整行输入,长度限制 100,足够使用。pwd 作为临时缓冲区,配合 len 逐步构建当前密码。main 函数的循环中,遇到逗号就结束当前密码并检查,非逗号字符则拼接到 pwd 中。check 严格按照题目要求的顺序判断,一旦不符合就提前返回 false,效率较高。!@#$ 四种,不要漏掉或多加。len 为 0,根据长度检查会直接判为不合法,符合题意。