问题描述
解题思路
unordered_map <string, int> p; //存储所有权限集合(包括有等级权限和有等级权限)
unordered_map <string, unordered_map <string, int>> r; //存储所有角色包含的所有权限(所含权限的最大等级值)
unordered_map <string, unordered_map <string, int>> u; //存储所有用户包含的所有权限(所含权限的最大等级值)
根据读入将权限(对应的等级)、角色(对应的权限)、用户(对应的权限)进行存储
再根据存储的集合进行权限查询
if (没有该用户) false
else if (该用户没有该权限) false
else(该用户拥有该权限)
{
if (该权限是无等级权限) true
else(该权限是有等级权限)
{
if (该查询是有等级查询)
{
if (拥有该查询等级权限)true
else(不拥有该查询等级权限)false
}
else(该查询是无等级查询)
{
if (不具有该类的任何等级权限)false
else (返回具有该类权限的等级)
}
}
}
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
unordered_map <string, int> p; //存储所有权限集合(包括有等级权限和有等级权限)
unordered_map <string, unordered_map <string, int>> r; //存储所有角色包含的所有权限(所含权限的最大等级值)
unordered_map <string, unordered_map <string, int>> u; //存储所有用户包含的所有权限(所含权限的最大等级值)
void work(string &str, int &x) //将含有冒号的表达式进行名字和等级的划分
{
int n = str.size();
if (n >= 2 && str[n - 2] == ':') //因为题目中指出等级只有可能是一位数字,所以如果存在,则一定是最后一位
{
x = str[n - 1] - '0';
str = str.substr(0, n - 2);
}
//cout << str << " " << x << endl;
}
int main()
{
int n;
cin >> n;
//存储权限
for (int i = 0; i < n; i ++)
{
string str = "";
int x = -1;
cin >> str;
work(str, x);
p[str] = x;
}
//存储角色
cin >> n;
for (int i = 0; i < n; i ++)
{
string name;
cin >> name;
int num;
cin >> num;
for (int j = 0; j < num; j ++)
{
string str = "";
int x = -1;
cin >> str;
work(str, x);
if (r[name].count(str) == 0) r[name][str] = x; //该角色还没有存储过该权限
else if (r[name][str] < x) r[name][str] = x; //该角色已存储的该权限的权限值小,更新该权限值
}
}
//存储用户
cin >> n;
for (int i = 0; i < n; i ++)
{
string name;
cin >> name;
int num;
cin >> num;
for (int j = 0; j < num; j ++)
{
string role = "";
cin >> role;
unordered_map <string, int > t = r[role]; //该用户拥有的角色所拥有的权限集合
for (auto x : t) //遍历权限集合,将其更新加入用户对应的权限集合中
{
string privilege = x.first;
int level = x.second;
if (u[name].count(privilege) == 0) u[name][privilege] = level;
else if (u[name][privilege] < level) u[name][privilege] = level;
}
}
}
//查询权限
cin >> n;
while (n --)
{
string uname;
cin >> uname;
string privilege;
int level = -1;
cin >> privilege;
work(privilege, level);
if (u.count(uname) == 0) puts("false"); //没有该用户
else if (u[uname].count(privilege) == 0) puts("false"); //该用户没有该权限
else //该用户拥有该权限
{
if (p[privilege] == -1) puts("true"); //该权限是无等级权限
else //该权限是有等级权限
{
if (level != -1) //该查询是有等级查询
{
if (u[uname][privilege] >= level) puts("true"); //拥有该查询等级权限
else puts("false");//不拥有该查询等级权限
}
else//该查询是无等级查询
{
if (u[uname][privilege] == -1) puts("false"); //不具有该类的任何等级权限
else cout << u[uname][privilege] << endl; //返回具有该类权限的等级
}
}
}
}
return 0;
}