题目的主要信息:

  • 验证输入的密码是否符合要求,输入一组或者多组长度超过2的字符串,要求输出OK(符合要求)或者NG(不符合要求)

  • 密码要求:

    1. 长度超过8位

    2. 包括大小写字母.数字.其它符号,以上四种至少三种

    3. 不能有相同长度大于2的子串重复

方法一:暴力验证

具体做法:

分三步依次检查上面的要求就行了。

  1. 首先检查输入的字符串长度,如果不大于8,输出NG,后面不用管;

  2. 准备一个长度为4的辅助数组,初始为0,遍历字符串,检查每种字符是否出现,如果出现则数组相应位置置为1,最后数组4个元素相加,如果小于3,还是输出NG,后面不用管;

  3. 最后我们要检查是否有相同长度大于2的字串重复,大于2,那我们找长度为3的重复子串就行了,因为大于3的也一定包含了这个3。两层遍历字符串,指针之间间隔三个,用substr函数截取两个下标开始的三位字符,检查是否相同,若是相同,也是NG。

alt

最后经过上述步骤都不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;
}

复杂度分析:

  • 时间复杂度:O(n2)O(n^2)nn为单次密码长度,验证重复子串两层循环遍历字符串
  • 空间复杂度:O(1)O(1),字符串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;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),正则表达式匹配复杂度为O(n)O(n)
  • 空间复杂度:O(1)O(1),常数级空间,字符串s属于必要空间