【华为od刷题(C++)】HJ20 密码验证合格程序

我的代码:

#include //引入输入输出流
#include //引入vector容器类,用于存储动态数组
#include //引入string类,用于处理字符串类型
#include //引入map类,尽管在这段代码中并未使用该头文件
using namespace std;

int main() {
    vector input;//用来存储输入的字符串
    vector result;//用来存储验证结果("OK" 或 "NG")
    string in;//用于逐个接收输入的字符串

    while (cin >> in) {
        //使用cin>>in从标准输入读取字符串,直到没有更多的输入为止
        int lower = 0;//小写字母
        int upper = 0;//大写字母
        int number = 0;//数字
        int other = 0;//其他字符的数量
        int flag = 0;//flag标志,用来表示字符串是否符合条件

        if (in.size() <= 8) {
            result.push_back("NG");
            //push_back("NG") 是 vector 类的一个成员函数
            //用来在 vector 的末尾添加一个元素
            continue;
        }
        //如果字符串长度小于等于8,则直接将结果标记为NG
        //并跳过当前循环(使用continue)

        for (int i = 0; i < in.size(); ++i) {
            if (in[i] >= 65 & in[i] <= 90)
                upper++;
            else if (in[i] >= 97 & in[i] <= 122)
                lower++;
            else if (in[i] >= 48 & in[i] <= 57)
                number++;
            else
                other++;
        }
        /*这段代码对字符串中的每个字符进行遍历,统计字符的类型:
        大写字母:ASCII值在65到90之间(A-Z)
        小写字母:ASCII值在97到122之间(a-z)
        数字:ASCII值在48到57之间(0-9)
        其他字符:所有不属于上述类别的字符*/

        if (lower != 0)flag++;
        if (upper != 0)flag++;
        if (number != 0)flag++;
        if (other != 0)flag++;
        if (flag < 3) {
            result.push_back("NG");
            continue;
        }
        /*这里检查字符种类是否满足要求
        flag记录不同类型的字符是否出现过:
        如果出现了小写字母、出现了大写字母、出现了数字、或出现了其他字符,
        flag的对应项会增加
        如果flag小于3,表示字符种类不足3种(至少要求3种不同的字符),
        则输出NG并跳过当前循环*/

        bool isfind = false;
        for (int i = 0; i < in.size() - 2; ++i) {
        //i < in.size() - 2 确保了 i 最大只能到 in.size() - 3
        //这样 in.substr(i, 3) 在最后一次循环时不会超出字符串的长度限制

        //例如,如果字符串长度是 10,索引范围是 0 到 9
        //为了确保每次提取的 3 个字符不会越界,i 必须小于 10 - 3 = 7,即最后一次有效的 i 是 6

            string temp = in.substr(i, 3);
            //使用substr(i, 3)从位置i开始提取一个长度为3的子串

            if (in.find(temp, i + 3) != in.npos) {
                //in 是目标字符串
                //temp 是要查找的子串
                //i + 3 是指定的起始位置
                //表示从字符串 in 中位置 i + 3 开始查找子串 temp

                //npos 是 std::string 类的一个常量
                //通常用于表示“未找到”或者“无效的位置”

                isfind = true;
                break;
            }
            //使用find方法在剩余的部分查找这个子串
            //如果找到了,find返回该子串的起始位置,npos表示没有找到
        }
        if (isfind) {
            result.push_back("NG");
            continue;
        }//如果存在重复的子串,则将结果设置为NG并跳过当前循环
        result.push_back("OK");
    //如果字符串满足所有条件(长度、字符种类、没有重复子串),则将结果标记为OK
    }
    
    for (auto i : result) {
        cout << i << endl;
    }//程序输出所有字符串的验证结果(OK或NG)

    return 0;
}

代码逻辑和思路概述:

  1. 输入字符串:使用 cin >> in 从标准输入读取字符串,直到没有更多输入为止

  2. 验证条件

    1. 长度限制:如果字符串长度小于或等于 8,直接标记为 "NG"(不满足条件)

    2. 字符种类统计

      • 遍历字符串的每个字符,统计小写字母、大写字母、数字和其他字符的数量
      • 如果字符串中包含的字符种类不足 3 种(即没有至少小写字母、大写字母、数字或其他字符中的 3 种),则标记为 "NG"
    3. 重复子串检查:对字符串进行遍历,提取每个长度为 3 的子串,然后检查是否有重复的子串;如果有重复的子串,则标记为 "NG"。

  3. 结果存储:每个字符串的验证结果("OK" 或 "NG")会被存储在 result 向量中

  4. 输出结果:最后,遍历并输出每个字符串的验证结果

关键步骤:

  • 字符分类:通过 ASCII 码范围检查字符类型(小写字母、 大写字母、数字、其他字符)
  • 字符种类检查:使用 flag 变量记录不同种类的字符出现情况,若少于 3 种种类则输出 "NG"
  • 重复子串检查:使用 substr() 提取长度为 3 的子串,然后用 find() 方法检查是否有重复出现的子串

你可能感兴趣的:(【华为od刷题(C++)】HJ20 密码验证合格程序)