题解 | #密码强度等级#
密码强度等级
http://www.nowcoder.com/practice/52d382c2a7164767bca2064c1c9d5361
题意
给定了一系列密码规则,根据这套规则得出密码的总分,不同总分输出不同提示
限制:密码长度不大于300
规则
题目直接给出的就是规则
一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 全都是小(大)写字母
20 分: 大小写混合字母
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号
五、奖励:
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号
最后的评分标准:
>= 90: 非常安全
>= 80: 安全(Secure)
>= 70: 非常强
>= 60: 强(Strong)
>= 50: 一般(Average)
>= 25: 弱(Weak)
>= 0: 非常弱
方法
翻译实现
直接把题目逐字逐句翻译成代码
代码
#include<bits/stdc++.h>
using namespace std;
int main(){
char s[310];
while(~scanf("%s",s)){ // 读入字符串
int c = 0; // 累计得分
int n = strlen(s); // 字符串长度
if(n < 5) c+=5; // 小于等于4 个字符
else if(n < 8)c+=10; // 5 到7 字符
else c+=25;
bool la = false; // 小写字母是否存在
bool ua = false; // 大写字母是否存在
int num = 0; // 数字出现次数
int sig = 0; // 符号出现次数
for(int i = 0;i < n;i++){
la = la || islower(s[i]); // 小写字母
ua = ua || isupper(s[i]); // 大写字母
num += isdigit(s[i]); // 数字
if(
(s[i] >= 0x21 && s[i] <= 0x2f) ||
(s[i] >= 0x3a && s[i] <= 0x40) ||
(s[i] >= 0x5b && s[i] <= 0x60) ||
(s[i] >= 0x7b && s[i] <= 0x7e)
){ // 符号
sig ++;
}
}
if(la && ua) c+=20; // 大小写混合字母
else if(la || ua) c+=10; // 全都是小(大)写字母
else c+=0;
if(num > 1) c+=20; // 大于1 个数字
else if(num == 1) c+=10; // 1 个数字
else c+=0;
if(sig > 1) c+=25; // 大于1 个符号
else if(sig == 1) c+=10; // 1 个符号
else c+=0;
if(sig && num && la && ua) c+= 5; // 大小写字母、数字和符号
else if(sig && num && (la || ua)) c+=3; // 字母、数字和符号
else if(num && (la || ua)) c+=2; // 字母和数字
if(c >= 90) printf("VERY_SECURE\n");
else if(c>=80) printf("SECURE\n");
else if(c>=70) printf("VERY_STRONG\n");
else if(c>=60) printf("STRONG\n");
else if(c>=50) printf("AVERAGE\n");
else if(c>=25) printf("WEAK\n");
else if(c>=0) printf("VERY_WEAK\n");
}
return 0;
}
复杂度分析
时间复杂度: 对于字符串遍历过程,操作为常数代价,剩余部分判断都是常数代价,所以时间复杂度为
空间复杂度: 主要消耗在字符串存储,空间复杂度为
ASCII优化
注意到这里虽然题目提供了ASCII码的具体数值,但是实际上在C++可以直接把char与int进行比较,会让char变为其ascii值。因此这里我们可以直接书写其实和结束的字符,而不需要知道它的具体值
代码
#include<bits/stdc++.h>
using namespace std;
int main(){
char s[310];
while(~scanf("%s",s)){
int c = 0;
int n = strlen(s);
if(n < 5) c+=5; // 小于等于4 个字符
else if(n < 8)c+=10; // 5 到7 字符
else c+=25;
bool la = false;
bool ua = false;
int num = 0;
int sig = 0;
for(int i = 0;i < n;i++){
la = la || islower(s[i]); // 小写字母
ua = ua || isupper(s[i]); // 大写字母
num += isdigit(s[i]); // 数字
if( // 直接使用字符而不是数值
(s[i] >= '!' && s[i] <= '/') ||
(s[i] >= ':' && s[i] <= '@') ||
(s[i] >= '[' && s[i] <= '`') ||
(s[i] >= '{' && s[i] <= '~')
){ // 符号
sig ++;
}
}
if(la && ua) c+=20; // 大小写混合字母
else if(la || ua) c+=10; // 全都是小(大)写字母
else c+=0;
if(num > 1) c+=20; // 大于1 个数字
else if(num == 1) c+=10; // 1 个数字
else c+=0;
if(sig > 1) c+=25; // 大于1 个符号
else if(sig == 1) c+=10; // 1 个符号
else c+=0;
if(sig && num && la && ua) c+= 5; // 大小写字母、数字和符号
else if(sig && num && (la || ua)) c+=3; // 字母、数字和符号
else if(num && (la || ua)) c+=2; // 字母和数字
if(c >= 90) printf("VERY_SECURE\n");
else if(c>=80) printf("SECURE\n");
else if(c>=70) printf("VERY_STRONG\n");
else if(c>=60) printf("STRONG\n");
else if(c>=50) printf("AVERAGE\n");
else if(c>=25) printf("WEAK\n");
else if(c>=0) printf("VERY_WEAK\n");
}
return 0;
}
复杂度分析
时间复杂度: 对于字符串遍历过程,操作为常数代价,剩余部分判断都是常数代价,所以时间复杂度为
空间复杂度: 主要消耗在字符串存储,空间复杂度为