CCF201612(3)权限查询问题

思路:

第一步:用3个结构体数组表示用户、角色、权限的信息,定义如下:

struct Privilege  //定义权限 
{
	string name;
	int level;	
};
struct Role  //定义角色 
{
	string name;
	struct Privilege privilege[11];
	int priviNum;
};
struct User  //定义用户 
{
	string name;
	struct Role uRole[11];
	int roleNum; 
}; 

第二步:然后就是输入权限、角色、用户的信息。这里要理清关系:一个用户可以有多个角色,一个角色有多个权限

第三步:输入查询信息,开始查询:先查询用户信息,若用户存在,再遍历用户的角色,再遍历每个角色的权限信息,当权限名字相等时,判断查询的种类,根据查询的种类改变标识变量的值。

第四步:根据标识变量输出结果

AC代码(有点多):

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

struct Privilege  //定义权限 
{
	string name;
	int level;	
};
struct Role  //定义角色 
{
	string name;
	struct Privilege privilege[11];
	int priviNum;
};
struct User  //定义用户 
{
	string name;
	struct Role uRole[11];
	int roleNum; 
}; 
struct User user[101];
struct Role role[101];
struct Privilege pri[101]; 

int findRole(string name)
{
	int i;
	for(i = 0; i < 100; i++)
	{
		if(role[i].name == name)
		{
			return i;
		}
	}
	return -1;
}
int findUser(string name)
{
	int i;
	for(i = 0; i < 100; i++)
	{
		if(name == user[i].name)
		{
			return i;
		}
	}
	return -1;
}
struct Privilege getPrivilege(string quanxian)
{
	struct Privilege p;
	if(quanxian.find(":",0) != string::npos)  // 权限带等级 
	{
		int pos =  quanxian.find(":",0);
		p.name = quanxian.substr(0,pos);
		p.level = quanxian.at(quanxian.length()-1)-'0';
	}else  //不带等级 
	{
		p.name = quanxian;
		p.level = -1; 
	}
	return p;	
}
int findPrivilege(string name)
{
	int i;
	for(i = 0; i < 100; i++)
	{
		if(pri[i].name == name)
		{
			return i;
		}
	}
	return -1;
} 
int main()
{
	int p,u,r,i,j,q,k;
	string quanxian;
	cin>>p; 
	//输入权限
	for(i = 0; i < p; i++)
	{
		cin>>quanxian;
		pri[i] = getPrivilege(quanxian);	
	}
	cin>>r;
	//  输入角色
	for(i = 0; i < r; i++)
	{
		string username;
		cin>>role[i].name;
		cin>>role[i].priviNum;
		for(j = 0; j < role[i].priviNum; j++)  //输入角色的特权 
		{
			string quanxian;
			cin>>quanxian;
			role[i].privilege[j] = getPrivilege(quanxian);
		}
	} 
	cin>>u;
	//输入用户
	for(i = 0; i < u; i++)
	{
		cin>>user[i].name;
		cin>>user[i].roleNum;
		for(j = 0; j < user[i].roleNum; j++)
		{
			string rolename;
			cin>>rolename;
			user[i].uRole[j] = role[findRole(rolename)];
		}
	}
	cin>>q;
	// 开始查询
	for(i = 0; i < q; i++)
	{
		string name;
		string quanxian;
		cin>>name>>quanxian;
		int priviFlag = 0;
		int maxLevel = -1;
		if(findUser(name) != -1)  //找到用户 
		{
			User u = user[findUser(name)];
			for(j = 0; j < u.roleNum; j++)  // 遍历用户的角色 
			{
				for(k = 0; k < u.uRole[j].priviNum; k++)  //遍历每个角色的特权 
				{
					struct Privilege p;
					p = getPrivilege(quanxian);
					if (p.name == u.uRole[j].privilege[k].name)  //找到了带权限的用户 
					{
						 if(p.level == -1 && u.uRole[j].privilege[k].level == -1)  //不分等级权限的不分等级查询 
						 {
						 	priviFlag = 1;
						 }else if(p.level == -1 && u.uRole[j].privilege[k].level != -1) //分等级权限的不分等级查询 
						 {
						 	if(maxLevel < u.uRole[j].privilege[k].level)
							 {
							 	priviFlag = 1;
							 	maxLevel = u.uRole[j].privilege[k].level;
							 } 
						 }else if(p.level != -1 && u.uRole[j].privilege[k].level != -1)//分等级权限的分等级查询 
						 {
						 	if(p.level <= u.uRole[j].privilege[k].level)
							{
							 	priviFlag = 1;
							}
						 } 
					}
				}
			}
		}
		if(priviFlag == 1 && maxLevel != -1)
		{
			cout<<maxLevel<<endl;
		}else if(priviFlag == 1 && maxLevel == -1)
		{
			cout<<"true"<<endl;
		}else if(priviFlag == 0)
		{
			cout<<"false"<<endl;
		}	
	}
	return 0;
} 

PS:题中的“否”就是指“false”,题目出错了,真是无语,这么大的一个考试,出这种问题,若要输出“否”,在输出结果时候还得判断查询种类

笔记:以后对于这种查询类的题目,最好将查询方法全部用函数封装起来,这样也方便编码,思路更清晰,记得注释代码,每隔一段时间重构一下代码。

在输出结构时要仔细查看题目中给出的不同的限制条件,将条件列出来再解答,不然思路很乱。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------优化后代码明显少了很多

#include<iostream>
#include<string>
using namespace std;
struct Category{
	string name;
	int level;
};
struct Role{
	string roleName; 
	struct Category roleCategory[11];
	int categoryNum;
};
struct User{
	string userName;
	struct Role userRole[11];
	int roleNum; 
};
struct Category cate[101];
struct Role role[101];
struct User user[101]; 
int p,r,u,q;
struct Category getCategory(string s){
	int index;
	struct Category c;
	if((index = s.find(":",0))!= string::npos){
		c.name = s.substr(0,index);
		c.level = s.at(s.length()-1)-'0';
	}else{
		c.name = s;
		c.level = -1;
	}
	return c;
} 
int findUser(string name){
	int i;
	for(i = 0; i < u; i++){
		if(user[i].userName == name){
			return i;
		}
	}
	return -1;
}
int findRole(string roleName){
	int i;
	for(i = 0; i < r; i++){
		if(role[i].roleName == roleName){
			return i;
		}
	}
	return -1;
} 
void findCategory(struct User oneUser,string quanxian){
	int i,j;
	string quanxianName;
	int flag = 0;
	int level,index,maxLevel = -1;
	if((index = quanxian.find(":",0))!=string::npos){
		quanxianName = 	quanxian.substr(0,index);
		level = quanxian.at(quanxian.length()-1)-'0';
	}else{
		quanxianName = quanxian;
		level = -1;
	}
	for(i = 0; i < oneUser.roleNum; i++){
		struct Role oneRole = oneUser.userRole[i];
		for(j = 0; j < oneRole.categoryNum; j++){
			struct Category oneCategory = oneRole.roleCategory[j];
			// 不分等级权限的不分等级查询 
			if(oneCategory.name == quanxianName && oneCategory.level == level && level == -1){
				flag = 1;
			}
			//  分等级权限带等级查询
			if(oneCategory.name == quanxianName && level != -1 && oneCategory.level >= level){
				flag = 1;
			}
			//  分等级权限不带等级查询
			if(level == -1 && oneCategory.level != -1 && quanxianName == oneCategory.name){
				if(oneCategory.level > maxLevel){
					maxLevel = oneCategory.level;
					flag = 2;
				}
			} 
		}
	}
	if(flag == 1){
		cout<<"true"<<endl;
	}
	if(flag == 2){
		cout<<maxLevel<<endl;
	}
	if(flag == 0){
		cout<<"false"<<endl;
	}
}
int main(){
	int i,j;
	string s;
	cin>>p;
	// 输入权限 
	for(i = 0; i < p; i++){
		cin>>s;
		cate[i] = getCategory(s);
	}
	cin>>r;
	//输入角色 
	for(i = 0; i < r; i++){
		cin>>role[i].roleName;
		cin>>role[i].categoryNum;
		// 遍历输入角色的每个权限 
		for(j = 0; j < role[i].categoryNum; j++){
			cin>>s;
			role[i].roleCategory[j] = getCategory(s);
		}
	}
	cin>>u;
	//输入用户 
	for(i = 0; i < u; i++){
		cin>>user[i].userName;
		cin>>user[i].roleNum;
		int index;
		for(j = 0; j < user[i].roleNum; j++){
			cin>>s;
			if((index = findRole(s))!= -1){
				user[i].userRole[j] = role[index];
			}
		}
	}
	cin>>q;
	//开始查询
	while(q--){
		string name;
		string quanxian;
		cin>>name>>quanxian; 
		int index;
		//用户查询
		if((index = findUser(name))!= -1){	//找到用户 
			struct User oneUser = user[index];
			findCategory(oneUser,quanxian);
		}else{
			cout<<"false"<<endl;
		} 
	} 
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值