洛谷B3843 [GESP202306 三级]密码合规

[GESP202306 三级] 密码合规

题目链接:https://www.luogu.com.cn/problem/B3843

题目描述

网站注册需要有用户名和密码,编写程序以检查用户输入密码的有效性。合规的密码应满足以下要求:。

1.只能由a-z之间26个小写字母, A-Z之间26个大写字母、0-9之间10个数字以及!@#$四个特殊字符构成。

2.密码最短长度:6个字符,密码最大长度:12个字符。

3.大写字母,小写字母和数字必须至少有其中两种,以及至少有四个特殊字符中的一个。

输入格式

输入一行不含空格的字符串。约定长度不超过100。该字符串被英文逗号分隔为多段,作为多组被检测密码。

输出格式

输出若干行,每行输出一组合规的密码。输出顺序以输入先后为序,即先输入则先输出。

样例 #1

样例输入 #1

seHJ12!@,sjdkffH$123,sdf!@&12HDHa!,123&^YUhg@!

样例输出 #1

seHJ12!@
sjdkffH$123

提示

【样例 1 解释】

输入被英文逗号分为了四组被检测密码:seHJ12!@sjdkffH$123sdf!@&12HDHa!123&^YUhg@!。其中 sdf!@&12HDHa! 长度超过 12 个字符,不合规;123&^YUhg@! 包含四个特殊字符之外的字符不合规。

这题我们可以使用getline函数读取一行的字符串,接收输入的字符串。

随后我们可以利用一个动态数组,存放每一个需要鉴定的字符串,我们这里拿vector来操作,因为vector提供了丰富的成员函数,操作起来较为方便。

我们使用一个string类的字符串current,来存取当前需要读取的字符串。然后就是一个逻辑问题了,我们如何能够跳过每一个空格读取字符串呢?——

我们可以在for循环中遍历这个大的字符串input,然后在遍历的过程中,以是否碰见','为判断条件,如果没有遇见空格的话,就一直读取,如果碰见了空格,就将当前字符串传入vector数组中,并且将当前

字符串置空,这样我们就可以读取下一个字符串了。

提醒:

但是,这种方法无法提取到最后一个字符串,因为input字符串不是以','结尾的。不过没关系,我们给它提供一个特殊处理逻辑就可以了

以上逻辑的C++示例代码如下:

	string input;
	cin >> input;
	vector<string> result(100);
	//用来遍历当前所需要读取的字符串
	string current;
	//遍历input字符串(基于范围的for循环)
	for (char ch : input) {
	    //如果没遇到逗号,就继续读取
		if (ch != ',') current.push_back(ch);
		else {
		    //遇见了逗号说明该遍历下一个字符串了
			if (!current.empty()) {
				result.push_back(current);
				current.clear();
			}
		}
	}
	//单独处理最后一个字符串
	if (!current.empty()) result.push_back(current);

然后,我们只需要定义一个函数,用来判断这个字符串是否合规,最后,遍历这个vector数组中的每一个字符串进行判断即可。

如何定义这个函数呢?

首先,我们需要传入的参数是一个字符串类型的变量,我们可以设置三个bool类型的值,用来判断三个条件中是否至少满足其中两个(大写字母,小写字母和数字)。

然后,用一个变量typeCount,用来判断即可。剩下的“不能出现#@!$”这四个符号以外的符号,这个逻辑,我们也只需要用一个bool类型的变量hasSpecial来判断即可,将这个bool类型的值初始化为false,

如果出现了这四个符号以及上述字母和数字之外的变量,那么我们就将其置为false即可,最后,看hasSpecial的值和typeCount的值即可判断。

C++示例代码如下:

int check(const string& s) {
    int size = s.size();
    //字符串长度小于6或者大于12,肯定不合规
    if (size < 6 || size > 12) return 0;
    //定义四个bool类型的变量,用于判断
    bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;

    for (char ch : s) {
        //判断出现字母,数字,和其他四个符合的if判断语句一定要写在一起
        if (ch >= 'a' && ch <= 'z') hasLower = true;
        else if (ch >= 'A' && ch <= 'Z') hasUpper = true;
        else if (ch >= '0' && ch <= '9') hasDigit = true;
        else if (ch == '!' || ch == '@' || ch == '#' || ch == '$') hasSpecial = true;
        else return 0; // 如果包含不允许的字符,则返回不符合要求
    }

    // 检查是否至少有两种不同的字符类型
    int typeCount = (hasLower ? 1 : 0) + (hasUpper ? 1 : 0) + (hasDigit ? 1 : 0);
    if (typeCount >= 2 && hasSpecial) return 1;
    return 0;
}

最后,整个程序的代码如下:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
int check(const string& s) {
    int size = s.size();
    //字符串长度小于6或者大于12,肯定不合规
    if (size < 6 || size > 12) return 0;
    //定义四个bool类型的变量,用于判断
    bool hasLower = false, hasUpper = false, hasDigit = false, hasSpecial = false;

    for (char ch : s) {
        //判断出现字母,数字,和其他四个符合的if判断语句一定要写在一起
        if (ch >= 'a' && ch <= 'z') hasLower = true;
        else if (ch >= 'A' && ch <= 'Z') hasUpper = true;
        else if (ch >= '0' && ch <= '9') hasDigit = true;
        else if (ch == '!' || ch == '@' || ch == '#' || ch == '$') hasSpecial = true;
        else return 0; // 如果包含不允许的字符,则返回不符合要求
    }

    // 检查是否至少有两种不同的字符类型
    int typeCount = (hasLower ? 1 : 0) + (hasUpper ? 1 : 0) + (hasDigit ? 1 : 0);
    if (typeCount >= 2 && hasSpecial) return 1;
    return 0;
}
int main()
{
	string input;
	cin >> input;
	vector<string> result(100);
	//用来遍历当前所需要读取的字符串
	string current;
	//遍历input字符串(基于范围的for循环)
	for (char ch : input) {
	    //如果没遇到逗号,就继续读取
		if (ch != ',') current.push_back(ch);
		else {
		    //遇见了逗号说明该遍历下一个字符串了
			if (!current.empty()) {
				result.push_back(current);
				current.clear();
			}
		}
	}
	//单独处理最后一个字符串
	if (!current.empty()) result.push_back(current);
	for (const string& password : result) {
		if (check(password) == 1) cout << password << endl;
	}

	return 0;
}
posted @ 2024-07-14 23:11  Tomorrowland_D  阅读(56)  评论(0编辑  收藏  举报