HJ20.密码验证合格程序
#include <iostream>
#include <string>
#include <unordered_set>
const std::string OK = "OK";
const std::string NG = "NG";
bool check1(const std::string& s) {
return s.length() > 8;
}
bool check2(const std::string& s) {
int type[4] = {0, 0, 0, 0};
for (auto& i : s) {
if (i == ' ' || i == '\n') {
return false;
}
if (i >= 'A' && i <= 'Z') {
type[0] = 1;
}else if (i >= 'a' && i <= 'z') {
type[1] = 1;
}else if (i >= '0' && i <= '9') {
type[2] = 1;
}else {
type[3] = 1;
}
}
if (type[0] + type[1] + type[2] + type[3] < 3) {
return false;
}
return true;
}
bool check3(const std::string& s) {
std::unordered_set<std::string> sets;
std::string tmp;
for (int i = 0; i < s.length() - 2; ++i) {
tmp = s.substr(i, 3);
if (sets.find(tmp) == sets.end()) {
sets.insert(tmp);
}else {
return false;
}
}
return true;
}
int main() {
std::string in;
while (getline(std::cin, in)) {
if (check1(in) && check2(in) && check3(in)) {
std::cout << OK << '\n';
}else {
std::cout << NG << '\n';
}
}
return 0;
}
解题思路:
难点1:题目本身,实在没搞清楚“3.不能有长度大于2的不含公共元素的子串重复 (注:其他符号不含空格或换行)”这句话的意思,什么叫“不含公共元素”是什么意思?最后是按照不含长度大于2的重复子串来做的;
难点2:重复子串的存在性判断。需要注意的是,这里只是判断有没有,并不是找出来,另外重复子串的长度是大于2,意味着我们只需要看长度为3的子串即可(如果有长度为4或者以上的子字符串,必然满足长度为3的重复子串存在!”;
难点3:如何快速找到子串吧,一种方式就是两层循环嵌套查找,时间复杂度比较高,题目没有对空间做限制,可以想到使用set快速查找,时间复杂度为O(n),相当于用空间换时间了;
难点4:密码中总共有几种字符类型,还是字典的思想,这里简单用数组来实现;