[C++] 密码检验合格程序
输入输出不多赘述,和之前的大同小异。判断合格有三点:
- 长度大于8,很好判断
- 至少三种类型,采用正则表达式来查找,因为C++采用的ECMAScript文法,和之前学习的正则表达式本身的语法不太一样,所以也学习了下C++的正则写法。这里注意
regex_match
和regex_search
两个函数的区别,如果整个序列和正则表达式匹配,则regex_match
返回true
;如果序列中一个子串与表达式匹配,则regex_search
返回true
。 不能有相同长度大于2的子串重复
,意味着重复子串长度一定大于等于3,而大于3的重复子串中一定包含长度为3的重复子串,所以只要检测有没有长度为3的重复子串就好,那么采用一个哈希表来存储子串,如果有重复的子串则明显不符合要求,如果遍历完了整个字符串都没有重复的,那么就可以确定整个字符串中没有长度为3的重复子串,也就满足了不能有相同长度大于2的子串重复
。当然需要如果整个字符串的长度小于等于3,那么就没必要检测重复子串了,直接返回true
。
#include<iostream> #include<regex> #include<unordered_map> using namespace std; bool isPasswordLegal(string &s) { if(s.length() <= 8) return false; // 正则表达式数组,遍历 int type = 0; vector<regex> patterns{regex ("[[:lower:]]"), regex ("[[:upper:]]"), regex ("[[:digit:]]"),regex ("[^[:alnum:]]")}; for (auto &pattern: patterns){ if (regex_search(s, pattern)) type += 1; } if (type < 3) return false; if (s.length() <= 3) return true; unordered_map<string, bool> m; for (int i = 0; i <= s.size() - 3; ++i){ string sub3 = s.substr(i, 3); if (!m.count(sub3)){ m[sub3] = true; } else{ return false; } } return true; } int main() { string s; while(cin>>s){ if(isPasswordLegal(s)){ cout<<"OK"<<endl; } else{ cout<<"NG"<<endl; } } return 0; }