当前位置: 首页 > news >正文

华为机试—密码验证合格程序

题目

你需要书写一个程序验证给定的密码是否合格。
合格的密码要求:

  • 长度超过 8 位
  • 必须包含大写字母、小写字母、数字、特殊字符中的至少三种
  • 不能分割出两个独立的、长度大于 2 的连续子串,使得这两个子串完全相同;更具体地,如果存在两个长度大于 2 的独立子串 s1​,s2​ ,使得 s1​=s2​ ,那么密码不合法。

子串为从原字符串中,连续的选择一段字符(可以全选、可以不选)得到的新字符串。

可见字符集为 ASCII 码在 33 到 126 范围内的可见字符。

示例

若密码合格,输出 OK ,否则输出 NG 。

示例1

输入:

021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
021Abc1111

输出:

OK
NG
NG
OK
OK

说明:对于第二组测试数据,"Abc9Abc1" 中存在两个长度大于 2 的独立子串 "Abc"。
           对于第三组测试数据,仅包含大写字母和数字,不满足条件。

示例2

输入:

Abc1@
A1@ababa@1A

输出:

NG
OK

说明:对于第一组测试数据,长度不足 8 位,不满足条件。

分析

哈希表+枚举

字符类型检查:在 hasThreeTypes 函数中,使用了遍历算法。通过遍历密码字符串中的每个字符,利用字符处理函数(如 std::isupperstd::islowerstd::isdigit)对字符进行分类判断,以确定密码中是否包含大写字母、小写字母、数字和特殊字符。

重复子串检查:在 hasRepeatedSubstring 函数中,结合了子串枚举和哈希表(std::unordered_set)的算法思想。首先,通过两层循环枚举所有可能的子串长度和起始位置,然后使用 std::unordered_set 来存储已经出现过的子串。在遍历过程中,如果发现某个子串已经存在于哈希表中,就说明存在重复子串。

时间复杂度:O(n^{2}), n 是字符串的长度

空间复杂度:O(n)

#include <iostream>
#include <string>
#include <unordered_set>
#include <cctype>

// 检查密码是否包含至少三种类型的字符
bool hasThreeTypes(const std::string& password) {
    bool hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;
    for (char c : password) {
        if (std::isupper(c)) hasUpper = true;
        else if (std::islower(c)) hasLower = true;
        else if (std::isdigit(c)) hasDigit = true;
        else if (c >= 33 && c <= 126) hasSpecial = true;
    }
    int typeCount = 0;
    if (hasUpper) ++typeCount;
    if (hasLower) ++typeCount;
    if (hasDigit) ++typeCount;
    if (hasSpecial) ++typeCount;
    return typeCount >= 3;
}

// 检查密码中是否存在两个长度大于 2 的相同独立连续子串
bool hasRepeatedSubstring(const std::string& password) {
    int n = password.length();
    for (int len = 3; len <= n / 2; ++len) {
        std::unordered_set<std::string> seen;
        for (int i = 0; i <= n - len; ++i) {
            std::string sub = password.substr(i, len);
            if (seen.find(sub) != seen.end()) {
                return true;
            }
            seen.insert(sub);
        }
    }
    return false;
}

// 验证密码是否合格
bool isPasswordValid(const std::string& password) {
    // 检查长度是否超过 8 位
    if (password.length() <= 8) return false;
    // 检查是否包含至少三种类型的字符
    if (!hasThreeTypes(password)) return false;
    // 检查是否存在两个长度大于 2 的相同连续子串
    if (hasRepeatedSubstring(password)) return false;
    return true;
}

int main() {
    std::string s;
    while (std::getline(std::cin, s)) {
        if (isPasswordValid(s)) {
            std::cout << "OK" << std::endl;
        } else {
            std::cout << "NG" << std::endl;
        }
    }
    return 0;
}    

相关文章:

  • GLSL(OpenGL 着色器语言)基础语法
  • 云计算初识
  • 如何使不同的窗体控件,适应不同分辨率的屏幕?
  • 从零开始:Windows 系统中 PowerShell 配置 FFmpeg 的详细步骤
  • 基于javaweb的SpringBoot驾校预约学习系统设计与实现(源码+文档+部署讲解)
  • Mysql 索引性能分析
  • 欢迎使用Markdown编辑器
  • 职能型组织、项目型组织、矩阵型组织的介绍及优缺点比较
  • 华为OD机试2025A卷 - 正则表达式替换(Java Python JS C++ C )
  • NX/UG二次开发—CAM获取加工操作的最低Z深度值的方法
  • 【数据结构篇】算法征途:穿越时间复杂度与空间复杂度的迷雾森林
  • 基于javaweb的SpringBoot实验室管理系统设计与实现(源码+文档+部署讲解)
  • 【差分隐私相关概念】差分隐私中的稀疏向量技术
  • Java虚拟机JVM知识点(持续更新)
  • 解决element plus el-dialog 被el-header覆盖问题
  • 【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的 AOP:实现日志记录与性能监控
  • 阻塞式IO与非阻塞IO的区别
  • 【当你在抖音滑动手指时,时间正在被做成期货交易】
  • 八股总结(go)实时更新!
  • 【AI大模型系列】DeepSeek V3的混合专家模型机制-MoE架构(八)
  • 怎样才能使网站排名靠前/商城系统开发
  • 网站 网址 域名/aso优化服务站
  • 做网站有一个火箭回顶部/域名whois查询
  • 网址站/重庆网站优化
  • 企业活动网站创意案例/在线的crm系统软件
  • 沙湾移动网站建设/小程序定制