《华为机试在线训练》之密码验证合格程序

题目描述

密码要求:


1.长度超过8位

 

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

 

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

 

说明:长度超过2的子串


输入描述:

一组或多组长度超过2的子符串。每组占一行

输出描述:

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

示例1

输入

021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出

OK
NG
NG
OK
       看题目的要求同样可以看到,其中分为三个部分处理,首先判断这个字符串的长度是否大于8,不大于8直接输出NG,大于8之后再继续判断是否包含三种以上不同的字符,如果不满足则直接输出NG,满足之后继续往下判断是否有长度大于2的重复子串,满足了之后才可以输出OK。所以最后是三个条件相与的情况,即认为三个条件都满足的情况才可以达到要求。分阶段处理如下:

一,长度判断

       长度判断是非常简单的,直接调用字符串类的处理函数,使用str.length()函数就可以直接求出长度,比较一下就可以

str.length()>8
       该表达式为true时继续往下进行判断,反之输出NG。

二,字符种类判断

       在这里我讲字符分为四种,一种为0~9,第二种为A~Z,第三种为a~z,第四种为其他字符,编写一个循环,在循环中遍历字符串中每一个字符,判断每一个字符属于哪一种,有相应类别的字符就将其标准flag赋值为1,最后求所有flag的总和,如果总和大于3就认为满足条件,否则不满足条件,输出NG,这样判断还会比较高效的,时间复杂度为o(n),还可以接受。代码如下

       

bool get_kind(string &str)               //种类判断子函数
{
    int flag1=0,flag2=0,flag3=0,flag4=0;
    int a=str.length();
    for(int i=0;i<a;i++)
    {
        if(str[i]>='0'&&str[i]<='9')       //判断是否为数字
            flag1=1;
        else {
                if(str[i]>='A'&&str[i]<='Z')   //判断是否为大写字母
                   flag2=1;
                else
                {
                    if(str[i]>='a'&&str[i]<='z')    //判断是否为小写字母
                      flag3=1;
                    else
                      flag4=1;                      //判断是否为其他字符,赋值标志位为1
                 }
             }
    }
    if((flag1+flag2+flag3+flag4)>2)                //判断最后的种类是否为3种以上,如果是则返回true,否则返回false。
        return true;
    else
        return false;
}
三,重复性子串长度判断

        首先编写一个子串长度函数,在该函数中处理两个字符串的长度,两个长度相等的话则返回长度值,否则跳出判断继续大循环中的下一次循环。代码如下

    

size_t getCommLen(string str1, string str2) {
    size_t i;
    for (i = 0; i < str1.size() && i < str2.size(); i++) {
        if (str1[i] != str2[i])
            break;
    }
    return i;
}
       接着编写求最大长度子串的函数,循环对每一个重复子串的长度进行比较,每一次都取最大重复子串的长度值,最后求得的就是最大的长度。其中使用到了vector的push_back()函数和sort()排序函数,具体的用法在这里就不解释了,可以去百度查阅一下具体用法。最后加一个判断最大长度是否大于2的if else,大于2的就输出false,否则为true。这样就可以完成判断要求。代码如下:

    

bool get_repeat(string &str)
{
    vector<string> strs;
    int b=str.size();
    for (int i = 0; i <b; i++) {
        strs.push_back(str.substr(i));
    }
    sort(strs.begin(), strs.end());

    int maxLen = 0;
    int c=strs.size();
    for (int i = 0; i < c-1; i++)
        {
        int len = getCommLen(strs[i], strs[i+1]);
        maxLen = max(maxLen, len);
        }
     if(maxLen>2)
        return false;
     else
        return true;
}

四,输出判断

    让字符串满足上面三个子函数的条件才可以最后判断为OK,否则就输出NG,这时一个if条件语句就可以判断完成。代码如下:

  

if(str.length()>8&&get_kind(str)&&get_repeat(str))
            cout<<"OK"<<endl;
        else
            cout<<"NG"<<endl;
五,完整代码如下;

    这里同样要注意测试用例是多组,所以一定要用while循环进行输出,才可以保证每一组测试用例都可以有正确的结果输出。

    

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
bool get_kind(string &str);
bool get_repeat(string &str);
size_t getCommLen(string str1, string str2);
int main()
{
    string str;
    while(cin>>str)
    {

        if(str.length()>8&&get_kind(str)&&get_repeat(str))
            cout<<"OK"<<endl;
        else
            cout<<"NG"<<endl;

    }
    //cout << "Hello world!" << endl;
    return 0;
}

bool get_kind(string &str)               //种类判断子函数
{
    int flag1=0,flag2=0,flag3=0,flag4=0;
    int a=str.length();
    for(int i=0;i<a;i++)
    {
        if(str[i]>='0'&&str[i]<='9')       //判断是否为数字
            flag1=1;
        else {
                if(str[i]>='A'&&str[i]<='Z')   //判断是否为大写字母
                   flag2=1;
                else
                {
                    if(str[i]>='a'&&str[i]<='z')    //判断是否为小写字母
                      flag3=1;
                    else
                      flag4=1;                      //判断是否为其他字符,赋值标志位为1
                 }
             }
    }
    if((flag1+flag2+flag3+flag4)>2)                //判断最后的种类是否为3种以上,如果是则返回true,否则返回false。
        return true;
    else
        return false;
}

bool get_repeat(string &str)
{
    vector<string> strs;
    int b=str.size();
    for (int i = 0; i <b; i++) {
        strs.push_back(str.substr(i));
    }
    sort(strs.begin(), strs.end());

    int maxLen = 0;
    int c=strs.size();
    for (int i = 0; i < c-1; i++)
        {
        int len = getCommLen(strs[i], strs[i+1]);
        maxLen = max(maxLen, len);
        }
     if(maxLen>2)
        return false;
     else
        return true;
}

size_t getCommLen(string str1, string str2) {
    size_t i;
    for (i = 0; i < str1.size() && i < str2.size(); i++) {
        if (str1[i] != str2[i])
            break;
    }
    return i;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值