密码验证合格程序

密码验证合格程序

描述
密码要求:

1.长度超过8位

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

3.不能有长度大于2的不含公共元素的子串重复 (注:其他符号不含空格或换行)

数据范围:输入的字符串长度满足

本题有多组输入
输入描述:
一组或多组字符串。每组占一行

输出描述:
如果符合要求输出:OK,否则输出NG

示例1
输入:

021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出:

OK
NG
NG
OK

方法一:暴力遍历

#include<iostream>
#include<string>
using namespace std;

bool legal(string str){
    if(str.size()<=8){
        return false;
    }
    bool number=false;
    bool Ch=false;
    bool ch=false;
    bool others=false;
    int count=0;
    for(int i=0;i<str.size();++i){
        if(str[i]>='a' && str[i]<='z') ch=true;
        else if(str[i]>='A' && str[i]<='Z') Ch=true;
        else if(str[i]>='0' && str[i]<='9') number=true;
        else if(str[i]!=' ' && str[i]!='\n') others=true;
    }
    if(number) count++;
    if(Ch) count++;
    if(ch) count++;
    if(others) count++;
    if(count<3){
        return false;
    }
    //1.验证是否有长度大于2的子串重复,只需要验证是否有长度为3的子串重复即可;
    //2.由于每一次比较,最后一个长度为3的子串都会被比较,因此暴力遍历的时候的基准不用选择最后一个,所以
    //基准遍历终点为len-6,即最后一个基准子字符串是倒数第二个子字符串
    for(int i=0;i<=str.size()-6;++i){
        for(int j=i+3;j<str.size()-2;++j){
            if(str.substr(i,3)==str.substr(j,3)) return false;
        }
    }
    return true;
}
int main(){
    string str="";
    while(getline(cin,str)){
        if(legal(str)){
            cout<<"OK"<<endl;
        }
        else cout<<"NG"<<endl;
    }
    return 0;
}

方法二:正则表达式

#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个字符一样的
        //regex pattern(".*(...).*\\1.*");
        if(regex_search(s, pattern))
            cout << "NG" << endl;
        else
            cout << "OK" << endl;
    }
    return 0;
}

补充正则知识:
1.. 匹配除“\n”之外的任何单个字符。若要匹配包括“\n”在内的任意字符,请使用诸如“[\s\S]”之类的模式。
2.* 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配“z”“zoo”* 等效于 {0,}
3. 匹配分组

regex e("(abc)de+");	// ()       ()表示一个子分组

4.匹配子分组

regex e("(abc)de+\\1");			// ()       ()表示一个子分组,而\1表示在此位置匹配第一个分组的内容
regex e("(abc)c(de+)\\2\\1");			// \2		表示的是在此匹配第二个分组的内容

更多内容参考:
1.https://blog.csdn.net/wxf306989618/article/details/104435701
2.https://blog.csdn.net/qianpeng4/article/details/78495899

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值