您的位置:首页 > 其它

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

2017-08-20 12:23 302 查看


题目描述

密码要求:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  华为 机试