持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
描述
密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有长度大于2的包含公共元素的子串重复 (注:其他符号不含空格或换行)
数据范围:输入的字符串长度满足 1≤n≤100
输入描述:
一组字符串。
输出描述:
如果符合要求输出:OK,否则输出NG
示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000
输出:
OK
NG
NG
OK
题目的主要信息:
-
验证输入的密码是否符合要求,输入一组或者多组长度超过2的字符串,要求输出OK(符合要求)或者NG(不符合要求)
-
密码要求:
- 长度超过8位
- 包括大小写字母.数字.其它符号,以上四种至少三种
- 不能有相同长度大于2的子串重复
方法一:暴力验证
具体做法:
分三步依次检查上面的要求就行了。
- 首先检查输入的字符串长度,如果不大于8,输出NG,后面不用管;
- 准备一个长度为4的辅助数组,初始为0,遍历字符串,检查每种字符是否出现,如果出现则数组相应位置置为1,最后数组4个元素相加,如果小于3,还是输出NG,后面不用管;
- 最后我们要检查是否有相同长度大于2的字串重复,大于2,那我们找长度为3的重复子串就行了,因为大于3的也一定包含了这个3。两层遍历字符串,指针之间间隔三个,用substr函数截取两个下标开始的三位字符,检查是否相同,若是相同,也是NG。 最后经过上述步骤都不NG的,就是OK。
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
while(cin >> s){
if(s.length() <= 8){ //长度不超过不可行
cout << "NG" << endl;
continue;
}
int flag[4] = {0};
for(int i = 0; i < s.length(); i++){
if(s[i] >= 'A' && s[i] <= 'Z') //大写字母
flag[0] = 1;
else if(s[i] >= 'a' && s[i] <= 'z') //小写字母
flag[1] = 1;
else if(s[i] >= '0' && s[i] <= '9') //数字
flag[2] = 1;
else //其他符号
flag[3] = 1;
}
if(flag[0] + flag[1] + flag[2] + flag[3] < 3){ //符号少于三种
cout << "NG" << endl;
continue;
}
bool repute = false; //记录重复子串
for(int i = 0; i <= s.length() - 6; i++) //遍历检查是否有长度为3的相同的字串
for(int j = i + 3; j < s.length(); j++)
if(s.substr(i, 3) == s.substr(j, 3)){
repute = true;
break;
}
if(repute) //有重复
cout << "NG" << endl;
else
cout << "OK" << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,n为单次密码长度,验证重复子串两层循环遍历字符串
- 空间复杂度:,字符串s属于必要空间,flag数组只有常数个变量
方法二:正则表达式
具体做法:
不管是单独匹配小写字母、大写字母、数字、其他字符,还是匹配串中前后连续三个一样的字符,我们都可以用正则表达式。写出正则表达式以后,我们使用regex_search,只需要找到有可以匹配的,而不需要完全匹配。
#include<iostream>
#include<string>
#include<regex>
using namespace std;
int main(){
string s;
while(cin >> s){
if(s.length() <= 8){ //长度不超过不可行
cout << "NG" << endl;
continue;
}
string re[4] = { "[a-z]", "[A-Z]", "\\d", "[^a-zA-Z0-9]" }; //分别匹配小写字母、大写字母、数字、其他字符
int count = 0;
for (int i = 0; i < 4; i++) {
regex pattern(re[i]);
if (regex_search(s, pattern)) //只需要查找到,不要求完全匹配
count++;
}
if(count < 3){ //符号少于三种
cout << "NG" << endl;
continue;
}
regex pattern(".*(...)(.*\\1).*"); //匹配串前后连续3个字符一样的
if(regex_search(s, pattern))
cout << "NG" << endl;
else
cout << "OK" << endl;
}
return 0;
}
复杂度分析:
- 时间复杂度:,正则表达式匹配复杂度为
- 空间复杂度:,常数级空间,字符串s属于必要空间