试题编号: | 201612-3 |
试题名称: | 权限查询 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 授权 (authorization) 是各类业务系统不可缺少的组成部分,系统用户通过授权机制获得系统中各个模块的操作权限。 输入格式 输入第一行是一个正整数 p,表示不同的权限类别的数量。紧接着的 p 行被称为 P 段,每行一个字符串,描述各个权限。对于分等级权限,格式为 <category>:<level>,其中 <category> 是权限类名,<level> 是该类权限的最高等级。对于不分等级权限,字符串只包含权限类名。 输出格式 输出共 q 行,每行为 false、true,或者一个数字。false 表示相应的用户不具有相应的权限,true 表示相应的用户具有相应的权限。对于分等级权限的不带等级查询,如果具有权限,则结果是一个数字,表示该用户具有该权限的(最高)等级。如果用户不存在,或者查询的权限没有定义,则应该返回 false。 样例输入 3 样例输出 false 样例说明 样例输入描述的场景中,各个用户实际的权限如下: 评测用例规模与约定 评测用例规模: |
问题描述:(参见上文)。
问题分析:这个问题是RBAC问题,即基于角色的权限访问问题,是商业应用中必然出现的问题。商业应用中,通常将这些数据存储于数据库中。这个问题只要采用合适的数据结构来存储有关数据即可,查询处理过程相对比较简单。
程序说明:程序中,使用了三个类分别用来表示权限、角色和用户。因为角色和用户都具有权限,所以可设计权限为父类。测试样例中,似乎没有使用权限数据,对权限数据不做任何处理也可以得100分。本题可选用Map或List做数据结构,但相对而言HashMap更佳,一方面可以满足权限和等级的一一对应关系,去除重复数据;另一方面,较部分其他数据结构(如ArrayList)更节省空间。
提交后得100分的Java语言程序如下:(提交时最好除去所有注释,否则易引起编译错误)
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Scanner; import java.util.Set; public class Main { public static void main(String[] args) { int p, num_temp; String str; Scanner sc = new Scanner(System.in); p = sc.nextInt(); // 读入权限描述,数据无意义(仅用于使程序通过测试用例),因为用户只依赖于角色,而角色决定了所有可用的权限和等级 for (int i = 0; i < p; i++) { str = sc.next(); } // 读入角色描述 p = sc.nextInt(); Role[] roles = new Role[p]; for (int i = 0; i < p; i++) { Role role = new Role(sc.next()); num_temp = sc.nextInt(); Map<String, Integer> privileges = role.privileges; for (int j = 0; j < num_temp; j++) { str = sc.next(); String[] pItem = str.split(":"); Integer topLevel = null; if (pItem.length == 2) { topLevel = Integer.parseInt(pItem[1]); Integer level = privileges.get(pItem[0]); if (level != null) {// 取最大等级 topLevel = level > topLevel ? level : topLevel; } } privileges.put(pItem[0], topLevel); } role.setPris(privileges); roles[i] = role; } // 输入用户描述 p = sc.nextInt(); User[] users = new User[p]; for (int i = 0; i < p; i++) { User user = new User(sc.next()); Map<String, Integer> privileges = user.privileges; num_temp = sc.nextInt(); for (int j = 0; j < num_temp; j++) { String roleName = sc.next(); // 判断此角色是否存在 int k = 0; int len = roles.length; while (k < len) { if (roleName.equals(roles[k].name)) { break; } k++; } // 如果此角色存在,则把其下的所有权限,赋给用户 if (k != len) { Map<String, Integer> privilegesRole = roles[k].privileges; Set<Entry<String, Integer>> entrySet = privilegesRole .entrySet(); for (Entry<String, Integer> entry : entrySet) { String key = entry.getKey(); Integer topLevel = entry.getValue(); Integer level = privileges.get(key); // 若重复,保留权限大的 if (level != null) { topLevel = level > topLevel ? level : topLevel; } privileges.put(key, topLevel); } } } user.setPris(privileges); users[i] = user; } // 对输入的用户、权限进行检查 p = sc.nextInt(); String[] results = new String[p]; for (int i = 0; i < p; i++) { String userName = sc.next(); str = sc.next(); String flag = "false"; for (User user : users) { if (userName.equals(user.name)) { // 判定该用户是否有输入的权限 Map<String, Integer> authorities = user.privileges; String[] auth = str.split(":"); Set<Entry<String, Integer>> entrySet = authorities .entrySet(); for (Entry<String, Integer> entry : entrySet) { if (auth[0].equals(entry.getKey())) { flag = "true"; Integer ownLevel = entry.getValue(); if (auth.length == 2) { int level = Integer.parseInt(auth[1]); if (ownLevel != null && level <= ownLevel) { flag = "true"; } else flag = "false"; } else { if (ownLevel != null) { flag = ownLevel.toString(); } } } } } } results[i] = flag; } sc.close(); // 打印结果 for (String result : results) { System.out.println(result); } } } class Privilege { String name; Map<String, Integer> privileges = new HashMap<String, Integer>(); public void setPris(Map<String, Integer> privileges) { this.privileges = privileges; } } class User extends Privilege { public User(String name) { this.name = name; } } class Role extends Privilege { public Role(String name) { this.name = name; } }