写在前面:
题目链接:牛客网 华为机试题 HJ20 密码验证合格程序
题目难度:中等
编程语言:C++
一、题目描述
描述
密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种 (注:其他符号不含空格或换行)
3.不能有长度大于2的包含公共元素的子串重复
数据范围:输入的字符串长度满足 [1,100]
输入描述:
一组字符串。
输出描述:
如果符合要求输出:OK,否则输出NG
示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
输出:
OK
NG
NG
OK
二、题目分析&解题思路
题目描述的很清楚,像是我们平常在注册账号的时候设置密码的密码校验过程,输入的密码需要满足一些条件,这样提高密码的难度,提升账号安全性,避免被轻易破解掉。
2.1 条件一 密码长度 大于 8
这个就很简单没有什么可讲的
bool isCurrSize(string& str)
{
return str.size() > 8;
}
2.2 包括大小写字母.数字.其它符号,以上四种至少三种 (注:其他符号不含空格或换行)
需要统计输入的密码中字符的种类,每一种用一个变量计数即可,注意空格和换行不算其他符号
bool isCurrKind(string& str)
{
int Big = 0;
int small = 0;
int number = 0;
int other = 0;
for(int i = 0; i < str.size();i++)
{
if(str[i] >= '0' && str[i] <= '9')//数字
{
if(number == 0)
{
number = 1;
}
}
else if(str[i] >= 'A' && str[i] <= 'Z')//大写字母
{
if(Big == 0)
{
Big = 1;
}
}
else if(str[i] >= 'a' && str[i] <= 'z')//小写字母
{
if(small == 0)
{
small = 1;
}
}
else
{
if(str[i] != ' ' && str[i] != '\n')//其他符号
{
if(other == 0)
{
other = 1;
}
}
}
}
if(Big + small + number + other >= 3)//种类大于 3
{
return true;
}
else
{
return false;
}
}
2.3 不能有长度大于2的包含公共元素的子串重复
这里大家应该都想到这是一道判断重复子串的问题,这里有一个条件,长度大于 2 ,那么就意味着
abcabd 这个字符串中虽有 重复子串 ab ,但是长度并不大于 2 ,因此这也是合法的密码,因此我们只需要将所有 长度为 3 的子字符串进行判断是否是重复的即可。
示例:
bool isHavePublicStr(string& str)
{
set<string> setResult;//用于判断是否重复
for(int i = 0; i < str.size()-3;i++)//注意越界
{
string strTemp = "";
strTemp =str.substr(i,3);//每次截取 3 个字符串即可
if(setResult.find(strTemp) == setResult.end())//判断是否重复
{
setResult.insert(strTemp);
}
else
{
return false;
}
}
return true;
}
三、代码实现
#include <iostream>
#include<string>
#include <vector>
#include<set>
using namespace std;
bool isCurrSize(string& str)
{
return str.size() > 8;
}
bool isCurrKind(string& str)
{
int Big = 0;
int small = 0;
int number = 0;
int other = 0;
for(int i = 0; i < str.size();i++)
{
if(str[i] >= '0' && str[i] <= '9')//数字
{
if(number == 0)
{
number = 1;
}
}
else if(str[i] >= 'A' && str[i] <= 'Z')//大写字母
{
if(Big == 0)
{
Big = 1;
}
}
else if(str[i] >= 'a' && str[i] <= 'z')//小写字母
{
if(small == 0)
{
small = 1;
}
}
else
{
if(str[i] != ' ' && str[i] != '\n')//其他符号
{
if(other == 0)
{
other = 1;
}
}
}
}
if(Big + small + number + other >= 3)//种类大于 3
{
return true;
}
else
{
return false;
}
}
bool isHavePublicStr(string& str)
{
set<string> setResult;//用于判断是否重复
for(int i = 0; i < str.size()-3;i++)//注意越界
{
string strTemp = "";
strTemp =str.substr(i,3);//每次截取 3 个字符串即可
if(setResult.find(strTemp) == setResult.end())//判断是否重复
{
setResult.insert(strTemp);
}
else
{
return false;
}
}
return true;
}
int main() {
string strCin;
while(getline(cin, strCin))//注意有多组输入
{
if(isCurrSize(strCin) && isCurrKind(strCin) && isHavePublicStr(strCin))
{
cout<<"OK"<<endl;
}
else
{
cout<<"NG"<<endl;
}
}
return 0;
}
运行结果: