B3843 [GESP202306 三级] 密码合规

题目描述

网站注册需要有用户名和密码,编写程序以检查用户输入密码的有效性。合规的密码应满足以下要求 :。

  1. 只能由 a∼z 之间 26 个小写字母、A∼Z 之间 26 个大写字母、0∼9 之间 10 个数字以及 !@#$ 四个特殊字符构成。

  2. 密码最短长度 :6 个字符,密码最大长度 :12 个字符。

  3. 大写字母,小写字母和数字必须至少有其中两种,以及至少有四个特殊字符中的一个。

输入格式

输入一行不含空格的字符串。约定长度不超过 100。该字符串被英文逗号分隔为多段,作为多组被检测密码。

输出格式

输出若干行,每行输出一组合规的密码。输出顺序以输入先后为序,即先输入则先输出。

输入输出样例

输入 #1

seHJ12!@,sjdkffH$123,sdf!@&12HDHa!,123&^YUhg@!

输出 #1

seHJ12!@
sjdkffH$123

题目分析

我们需要检查输入的密码是否满足以下条件:

  1. 字符范围:只能由 a-zA-Z0-9 以及 !@#$ 四个特殊字符构成。

  2. 长度限制:密码长度必须在 6 到 12 个字符之间。

  3. 字符类型要求

    • 大写字母、小写字母和数字必须至少有其中两种。

    • 必须包含至少一个特殊字符(!@#$)。

解决思路

  1. 分割输入:将输入字符串按逗号 , 分割成多个密码。

  2. 检查每个密码

    • 检查长度是否在 6 到 12 之间。

    • 检查是否只包含合法字符(a-zA-Z0-9!@#$)。

    • 检查是否包含至少两种字符类型(大写字母、小写字母、数字)。

    • 检查是否包含至少一个特殊字符。

  3. 输出合规的密码:按输入顺序输出满足条件的密码。


C++ 代码实现

#include 
#include 
#include 
#include 
using namespace std;

// 检查密码是否合规
bool isValidPassword(const string& password) {
    // 检查长度
    if (password.length() < 6 || password.length() > 12) {
        return false;
    }

    // 检查字符是否合法
    for (char ch : password) {
        if (!(isdigit(ch) || islower(ch) || isupper(ch) || ch == '!' || ch == '@' || ch == '#' || ch == '$')) {
            return false;
        }
    }

    // 检查是否包含至少两种字符类型(大写字母、小写字母、数字)
    bool hasLower = false, hasUpper = false, hasDigit = false;
    for (char ch : password) {
        if (islower(ch)) hasLower = true;
        if (isupper(ch)) hasUpper = true;
        if (isdigit(ch)) hasDigit = true;
    }
    int typeCount = 0;
    if (hasLower) typeCount++;
    if (hasUpper) typeCount++;
    if (hasDigit) typeCount++;
    if (typeCount < 2) {
        return false;
    }

    // 检查是否包含至少一个特殊字符
    bool hasSpecial = false;
    for (char ch : password) {
        if (ch == '!' || ch == '@' || ch == '#' || ch == '$') {
            hasSpecial = true;
            break;
        }
    }
    if (!hasSpecial) {
        return false;
    }

    return true;
}

int main() {
    string input;
    getline(cin, input); // 读取输入

    // 按逗号分割输入
    vector passwords;
    size_t start = 0;
    size_t end = input.find(',');
    while (end != string::npos) {
        passwords.push_back(input.substr(start, end - start));
        start = end + 1;
        end = input.find(',', start);
    }
    passwords.push_back(input.substr(start)); // 添加最后一个密码

    // 检查每个密码并输出合规的
    for (const string& password : passwords) {
        if (isValidPassword(password)) {
            cout << password << endl;
        }
    }

    return 0;
}

代码说明

  1. isValidPassword 函数

    • 检查密码长度是否在 6 到 12 之间。

    • 检查密码是否只包含合法字符。

    • 检查是否包含至少两种字符类型(大写字母、小写字母、数字)。

    • 检查是否包含至少一个特殊字符。

  2. 主函数

    • 读取输入字符串。

    • 按逗号 , 分割输入字符串,得到多个密码。

    • 对每个密码调用 isValidPassword 函数进行检查,如果合规则输出。

解释:
  • seHJ12!@:长度合规,包含大写字母、小写字母、数字和特殊字符 !@

  • sjdkffH$123:长度合规,包含大写字母、小写字母、数字和特殊字符 $

  • sdf!@&12HDHa!:长度超过 12 个字符,不合规。

  • 123&^YUhg@!:包含非法字符 & 和 ^,不合规。


复杂度分析

  1. 时间复杂度

    • 分割输入字符串的时间复杂度为 O(n),其中 n 是输入字符串的长度。

    • 对每个密码的检查时间复杂度为 O(m),其中 m 是密码的长度。

    • 总时间复杂度为 O(n + k * m),其中 k 是密码的数量。

  2. 空间复杂度

    • 使用 vector 存储分割后的密码,空间复杂度为 O(k * m)

    • 其他变量使用常数空间,空间复杂度为 O(1)


优化

如果输入字符串非常长,可以考虑使用更高效的分割方法(如手动遍历字符串)。但对于题目中的限制(长度不超过 100),当前方法已经足够高效。

你可能感兴趣的:(算法,c++,数据结构)