思路:
第一步:用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;
}