Main.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package CSP.A202303.A3;
  2. import java.util.*;
  3. /**
  4. * @Projectname: LeetCode
  5. * @Filename: CSP.A202303.A3.CSP.A202212.A3.CSP.temp.A1.CSP.temp.A2.CSP.temp.A3.CSP.temp.A4.CSP.temp.A5.Main
  6. * @Author: 杨逸
  7. * @Data:2023/8/31 20:40
  8. * @Description: LDAP-第二题
  9. */
  10. public class Main {
  11. private final static Scanner input = new Scanner(System.in);
  12. private final static Map<Integer, User> users = new HashMap<>();
  13. private final static List<List<Integer>> result = new ArrayList<>();
  14. private static int n;
  15. private static int m;
  16. public static void main(String[] args) {
  17. n = input.nextInt();
  18. for (int i = 0; i < n; i++) {
  19. int code = input.nextInt();
  20. //根据编号创建用户
  21. User user = new User(code);
  22. users.put(code, user);
  23. int count = input.nextInt();
  24. for (int j = 0; j < count; j++) {
  25. //设置用户的属性
  26. user.attribute.put(input.nextInt(), input.nextInt());
  27. }
  28. }
  29. //输入查询数量
  30. m = input.nextInt();
  31. //创建结果列表
  32. for (int i = 0; i < m; i++) {
  33. result.add(new ArrayList<>());
  34. }
  35. //进行查询
  36. StringBuilder temp = new StringBuilder();
  37. for (int i = 0; i < m; i++) {
  38. String sentence = input.next();
  39. List<Integer> list = result.get(i);
  40. //将查询字符串分割为多个基础表达式
  41. temp.delete(0, temp.length());
  42. int left = 0;
  43. //判断是否有两个组合的逻辑表达式
  44. int index = -1;
  45. for (int j = 1; j < sentence.length(); j++) {
  46. if ((sentence.charAt(j-1)=='&' && sentence.charAt(j)=='&') || (sentence.charAt(j-1)=='&' && sentence.charAt(j)=='|') ||
  47. (sentence.charAt(j-1)=='|' && sentence.charAt(j)=='&') || (sentence.charAt(j-1)=='|' && sentence.charAt(j)=='|')){
  48. index = j-1;
  49. break;
  50. }
  51. }
  52. if (index != -1){
  53. //存在两个组合逻辑表达式
  54. List<Integer> list1 = f2(sentence.substring(0, index));
  55. List<Integer> list2 = f2(sentence.substring(index+1, sentence.length()));
  56. //根据组合逻辑进行集合运算
  57. if (sentence.charAt(index)=='|'){
  58. //进行或操作
  59. for (Integer integer : list1) {
  60. if (!list2.contains(integer))list2.add(integer);
  61. }
  62. for (Integer integer : list2) {
  63. list.add(integer);
  64. }
  65. }else {
  66. //进行与操作
  67. for (Integer integer : list1) {
  68. if (list2.contains(integer))list.add(integer);
  69. }
  70. }
  71. }else{
  72. //只有一个逻辑表达式
  73. List<Integer> list1 = f2(sentence);
  74. //保存到结果集合
  75. for (Integer integer : list1) {
  76. list.add(integer);
  77. }
  78. }
  79. }
  80. //对查询结果进行排序
  81. for (List<Integer> list : result) {
  82. list.sort((v1, v2) -> v1 - v2);
  83. }
  84. //输出查询结果
  85. for (List<Integer> list : result) {
  86. for (Integer integer : list) {
  87. System.out.print(integer + " ");
  88. }
  89. System.out.println();
  90. }
  91. }
  92. //传进一个原子表达式,返回操作符以及属性以及属性值
  93. private static int[] f(String str) {
  94. int left = 0;
  95. StringBuilder temp = new StringBuilder();
  96. while (left < str.length() && str.charAt(left) != ':' && str.charAt(left) != '~') {
  97. temp.append(str.charAt(left++));
  98. }
  99. int attr = Integer.valueOf(temp.toString());
  100. temp.delete(0, temp.length());
  101. //操作符,true为 ":",false为 "~"
  102. int operate = str.charAt(left++) == ':' ? 1 : 0;
  103. //值
  104. //拼接值编号
  105. while (left < str.length()) {
  106. temp.append(str.charAt(left++));
  107. }
  108. int val = Integer.valueOf(temp.toString());
  109. //
  110. return new int[]{operate, attr, val};
  111. }
  112. //传进表达式和保存结果的列表,返回结果列表
  113. private static List<Integer> f2(String sentence){
  114. List<Integer> list = new ArrayList<>();
  115. StringBuilder temp = new StringBuilder();
  116. int left = 0;
  117. if (sentence.charAt(0)=='&' || sentence.charAt(0)=='|'){
  118. //逻辑表达式
  119. //判断是否与还是或
  120. if (sentence.charAt(left++)=='&'){
  121. //与操作
  122. //先用户中选出满足条件一的
  123. while(sentence.charAt(left) != ')' && left < sentence.length()){
  124. if (sentence.charAt(left)=='('){
  125. left++;
  126. continue;
  127. }
  128. temp.append(sentence.charAt(left++));
  129. }
  130. int[] f = f(temp.toString());
  131. temp.delete(0,temp.length());
  132. boolean flag = f[0]==1;
  133. int attr = f[1];
  134. int val = f[2];
  135. //将满足条件的加入
  136. ArrayList<Integer> list1 = new ArrayList<>();
  137. for (Integer integer : users.keySet()) {
  138. User user = users.get(integer);
  139. if (flag && user.attribute.containsKey(attr) && user.attribute.get(attr)==val){
  140. list1.add(user.code);
  141. }else if (!flag && user.attribute.containsKey(attr) && user.attribute.get(attr)!=val){
  142. list1.add(user.code);
  143. }
  144. }
  145. //筛选满足剩余条件的
  146. while(left < sentence.length()-1){
  147. left++;
  148. while(sentence.charAt(left) != ')' && left < sentence.length()){
  149. if (sentence.charAt(left)=='('){
  150. left++;
  151. continue;
  152. }
  153. temp.append(sentence.charAt(left++));
  154. }
  155. f = f(temp.toString());
  156. temp.delete(0,temp.length());
  157. flag = f[0]==1;
  158. attr = f[1];
  159. val = f[2];
  160. for (Integer integer : list1) {
  161. User user = users.get(integer);
  162. if (flag && user.attribute.containsKey(attr) && user.attribute.get(attr)==val){
  163. //满足条件,不进行操作
  164. }else if (!flag && user.attribute.containsKey(attr) && user.attribute.get(attr)!=val){
  165. //满足条件,不进行操作
  166. }else{
  167. //不满足条件删除
  168. list1.remove(Integer.valueOf(integer));
  169. }
  170. }
  171. }
  172. //保存最后的结果
  173. for (Integer integer : list1) {
  174. list.add(integer);
  175. }
  176. }else {
  177. //或操作
  178. //将所有满足条件的用户加入结果
  179. while(left < sentence.length()-1){
  180. left++;
  181. while(sentence.charAt(left) != ')' && left < sentence.length()){
  182. if (sentence.charAt(left)=='('){
  183. left++;
  184. continue;
  185. }
  186. temp.append(sentence.charAt(left++));
  187. }
  188. int[] f = f(temp.toString());
  189. temp.delete(0,temp.length());
  190. boolean flag = f[0]==1;
  191. int attr = f[1];
  192. int val = f[2];
  193. //到哈希表中查找
  194. for (Integer integer : users.keySet()) {
  195. User user = users.get(integer);
  196. if (flag && user.attribute.containsKey(attr) && user.attribute.get(attr)==val){
  197. if (!list.contains(Integer.valueOf(user.code)))list.add(user.code);
  198. }else if (!flag && user.attribute.containsKey(attr) && user.attribute.get(attr)!=val){
  199. if (!list.contains(Integer.valueOf(user.code)))list.add(user.code);
  200. }
  201. }
  202. }
  203. }
  204. }else{
  205. //原子表达式
  206. //属性
  207. //拼接属性编号
  208. int[] f = f(sentence);
  209. boolean flag = f[0]==1;
  210. int attr = f[1];
  211. int val = f[2];
  212. //到哈希表中查找
  213. for (Integer integer : users.keySet()) {
  214. User user = users.get(integer);
  215. if (flag && user.attribute.containsKey(attr) && user.attribute.get(attr)==val){
  216. if (!list.contains(Integer.valueOf(user.code)))list.add(user.code);
  217. }else if (!flag && user.attribute.containsKey(attr) && user.attribute.get(attr)!=val){
  218. if (!list.contains(Integer.valueOf(user.code)))list.add(user.code);
  219. }
  220. }
  221. }
  222. return list;
  223. }
  224. }
  225. class User {
  226. //用户类
  227. int code;
  228. Map<Integer, Integer> attribute = new HashMap<>();
  229. public User(int code) {
  230. this.code = code;
  231. }
  232. }