百姓网的面试题

原题在这里百姓网公开笔试题:查询条件的子集判断,这道题在5月份的时候就看到了,一直想做,中间学习python,断断续续知道今天才发布出来:(,不过也算自己干完了一件事。测试代码直接使用了赖总的

 
  
1 # -*-coding:utf-8-*-
2  
3 class BTree:
4 def __init__ (self, data):
5 self.l = None
6 self.r = None
7 self.data = data
8
9 def insertl(self, ltree):
10 self.l = ltree
11
12 def insertr(self, rtree):
13 self.r = rtree
14
15 def printTree(self, indent):
16 if isa(self.data, str):
17 print indent + self.data
18 else :
19 l, op, r = self.data
20 print indent + op,l,r
21
22
23 # BNF语法树解析
24 # Compare = > | < | =
25 # Atom = Field Compare Number
26 # SubSet = Atom|(Exp)*
27 # Factor = SubSet(and SubSet)*
28 # Exp = Factor(or Factor)*
29 isa = isinstance
30 conjunction = [ ' and ' , ' or ' ]
31 compare = [ ' > ' , ' < ' , ' = ' ]
32 keyword = [ ' and ' , ' or ' , ' > ' , ' < ' , ' = ' ]
33
34 def atom(token):
35 try : return int(token)
36 except ValueError:
37 try : return float(token)
38 except ValueError:
39 return str(token)
40
41 def getNumber(num):
42 if isa(num, str):
43 raise SyntaxError( ' should be number ' )
44 elif isa(num, list):
45 raise SyntaxError( ' should be number string ' )
46 else :
47 return num
48
49 def getField(field):
50 if isa(field, str):
51 if field in keyword:
52 raise SyntaxError( ' field should not be keyword ' )
53 else :
54 return field
55 else :
56 raise SyntaxError( ' field should not be number ' )
57
58 def getCompare(string):
59 if isa(string, str):
60 if string in compare:
61 return string
62 else :
63 raise SyntaxError( ' should be compare word ' )
64 else :
65 raise SyntaxError( ' should be compare string ' )
66
67 def getAtom(strSQL):
68 if len(strSQL) < 3 :
69 raise SyntaxError( ' should be leng ' )
70 atom = strSQL.pop(0)
71 field = getField(atom)
72
73 atom = strSQL.pop(0)
74 compare = getCompare(atom)
75
76 atom = strSQL.pop(0)
77 num = getNumber(atom)
78
79 L = []
80 L.append(field)
81 L.append(compare)
82 L.append(num)
83 subset = BTree(L)
84 return subset
85
86 def getSubSet(strSQL):
87 if isa(strSQL[0], str):
88 return getAtom(strSQL)
89 else :
90 atom = strSQL.pop(0)
91 return getExp(atom)
92
93 def getFactor(strSQL):
94 factor = getSubSet(strSQL)
95 while (len(strSQL) > 0):
96 op = strSQL.pop(0)
97 if op == ' and ' :
98 atom = getSubSet(strSQL)
99 else :
100 strSQL.insert(0, op)
101 break
102 factorOP = BTree(op)
103 factorOP.insertl(factor)
104 factorOP.insertr(atom)
105 factor = factorOP
106 return factor
107
108 def getExp(strSQL):
109 exp = getFactor(strSQL)
110 while (len(strSQL) > 0):
111 op = strSQL.pop(0)
112 if op == ' or ' :
113 factor = getFactor(strSQL)
114 else :
115 raise SyntaxError( ' keyword should be or ' )
116 break
117 expOP = BTree(op)
118 expOP.insertl(exp)
119 expOP.insertr(factor)
120 exp = expOP
121 return exp
122
123 # #########################
124 # 解析SQL字符串,得到语法树
125 # #########################
126 def tokenize(s):
127 for key in compare:
128 s = s.replace(key, ' ' + key + ' ' )
129 return s.replace( ' ( ' , ' ( ' ).replace( ' ) ' , ' ) ' ).split()
130
131 def read_fromPart(s):
132 L = []
133 while len(s) > 0:
134 ch = s.pop(0)
135 if ch == ' ) ' :
136 return L
137 elif ch == ' ( ' :
138 L.append(getPart(s))
139 else :
140 L.append(atom(ch))
141 if ch != ' ) ' :
142 raise SyntaxError( ' unexpcted ) part ' )
143 return L
144
145 def read_from(s):
146 L = []
147 while len(s) > 0:
148 ch = s.pop(0)
149 if ch == ' ) ' :
150 raise SyntaxError( ' unexpcted ) ' )
151 return L
152 elif ch == ' ( ' :
153 L.append(read_fromPart(s))
154 else :
155 L.append(atom(ch))
156
157 return L
158
159 def read(s):
160 return read_from(tokenize(s))
161
162 # 得到语法树
163 def pharse(stringExp):
164 strSQL = read(stringExp)
165 exp = getExp(strSQL)
166 return exp
167
168 # #########################
169 # 输出表达式
170 # #########################
171 INDENT = ' '
172 def outputExp(exp, indent):
173 if exp.data:
174 exp.printTree(indent)
175 if exp.l:
176 outputExp(exp.l, indent + INDENT)
177 if exp.r:
178 outputExp(exp.r, indent + INDENT)
179
180 def addtowlist(l, r):
181 result = []
182 for subsetl in l:
183 for subsetr in r:
184 for atom in subsetr:
185 subsetl.append(atom)
186 result.append(subsetl)
187 return result
188
189 # #########################
190 # 处理SQL表达式
191 # 将(A<10 OR A>20) AND (B<10 OR B>20)
192 # 变换成为:
193 # (A<10 AND B<10) OR (A<10 AND B>20) OR (A>20 AND B<10) OR (A>20 AND B>20)
194 # #########################
195 def normalizeExp(exp):
196 if not exp.l:
197 return [[exp.data]]
198 l = normalizeExp(exp.l)
199 r = normalizeExp(exp.r)
200 op = exp.data
201 result = []
202 if op == ' and ' :
203 result = addtowlist(l, r)
204 elif op == ' or ' :
205 for subsetl in l:
206 result.append(subsetl)
207 for subsetr in r:
208 result.append(subsetr)
209 return result
210
211 # #########################
212 # 判断是否为子集
213 # #########################
214 def is_subset_atom_atom (left, right):
215 assert left and right
216 ll, lop, lr = left
217 rl, rop, rr = right
218 assert lop in compare and rop in compare
219 if ll != rl:
220 return False
221 if lop == rop == ' > ' :
222 return lr >= rr
223 elif lop == rop == ' < ' :
224 return lr <= rr
225 elif lop == rop == ' = ' :
226 return lr == rr
227 elif lop == ' > ' :
228 return False
229 elif lop == ' < ' :
230 return False
231 elif lop == ' = ' :
232 if rop == ' > ' :
233 return lr > rr
234 elif rop == ' < ' :
235 return lr < rr
236 else :
237 raise RuntimeError( ' Error ' )
238
239 def get_sub_field(subset):
240 L = []
241 for x in subset:
242 l, op, r = x
243 if len(L) == 0:
244 L.append(l)
245 elif l not in L:
246 L.append(l)
247 return L
248
249 # 判断and子式的关系
250 def is_subset_sub(left, right):
251 assert left and right
252 fieldL = get_sub_field(left)
253 fieldR = get_sub_field(right)
254
255 for x in fieldR:
256 if x not in fieldL:
257 return False # age>10 不是 age>10 and weight>100的子集
258 b = False
259 if len(fieldR) == len(fieldL):
260 b = True
261
262 if b:
263 # 对于 age>10 and weight>10 和 age>20 and weight>20的子集
264 # 必须左子式的每个原子条件都是右子式任一原子条件的子集
265 for atoml in left:
266 bSubset = False
267 for atomr in right:
268 bSubset = is_subset_atom_atom(atoml, atomr)
269 if bSubset == True:
270 break
271 if bSubset == False:
272 return False
273 return True
274 else :
275 # 对于 age>10和 age>20 and weight>20的子集
276 # 只要左子式的有原子条件都是右子式任一原子条件的子集,则左子式为右子式的子集
277 for atoml in left:
278 bSubset = False
279 for atomr in right:
280 bSubset = is_subset_atom_atom(atoml, atomr)
281 if bSubset == True:
282 return True
283 return False
284
285 def is_subset_exp(left, right):
286 assert left and right
287 for subl in left:
288 b = False
289 for subr in right:
290 b = is_subset_sub(subl, subr)
291 if b == True:
292 break
293 if b == False:
294 return False
295
296 return True
297
298 class Query(object):
299 def __init__ (self, q):
300 self._q = q
301 self._tree = normalizeExp(pharse(q))
302 assert self._tree
303
304 def is_subset(self, other):
305 if not self._tree:
306 return False
307 if not other._tree:
308 return True
309 return is_subset_exp(self._tree, other._tree)
310
311
312 if __name__ == ' __main__ ' :
313 t0 = Query( ' age > 40 ' ) # 中年人
314 t1 = Query( ' age > 18 ' ) # 成年人
315 print t0.is_subset(t0)
316 print t0.is_subset(t1)
317 print t1.is_subset(t0)
318 print t1.is_subset(t1)
319 print ' - ' * 30
320
321 t2 = Query( ' age > 18 and weight < 100 ' ) # 成年瘦子
322 t3 = Query( ' age > 18 or weight < 100 ' ) # 成年人,或体重小于 100
323 print t0.is_subset(t2)
324 print t0.is_subset(t3)
325
326 print t2.is_subset(t0)
327 print t2.is_subset(t3)
328
329 print t3.is_subset(t2)
330
331 r0 = Query( ' age > 30 and sex = 0 ' )
332 r1 = Query( ' age > 40 and sex = 0 ' )
333
334 print r0.is_subset(r1)
335 print r1.is_subset(r0)
336 print ' = ' * 30
337
338 t0 = Query( ' (age < 15 and sex = 0) or age > 30 ' )
339 t1 = Query( ' age < 7 ' )
340 t2 = Query( ' age < 18 ' )
341
342 print ' * ' * 30
343 assert ' t0 is subset of t0: ' and t0.is_subset(t0) == True
344 print ' - ' * 30
345 assert ' t0 is subset of t1: ' and t0.is_subset(t1) == False
346 print ' - ' * 30
347 assert ' t1 is subset of t0: ' and t1.is_subset(t0) == False
348 print ' - ' * 30
349 assert ' t2 is subset of t0: ' and t2.is_subset(t0) == False
350 print ' - ' * 30
351
352 q0 = Query( ' age < 15 ' )
353 q1 = Query( ' age > 30 ' )
354 q2 = Query( ' age > 18 ' )
355 q3 = Query( ' age > 40 ' )
356 q4 = Query( ' age > 30 and sex = 0 ' )
357
358
359 assert ' q0 is subset of q0: ' and q0.is_subset(q0) == True
360 print ' - ' * 30
361 assert ' q0 is subset of q1: ' and q0.is_subset(q1) == False
362 print ' - ' * 30
363 assert ' q0 is subset of q2: ' and q0.is_subset(q2) == False
364 print ' - ' * 30
365 assert ' q0 is subset of q3: ' and q0.is_subset(q3) == False
366 print ' - ' * 30
367 assert ' q0 is subset of q4: ' and q0.is_subset(q4) == False
368 print ' - ' * 30
369 print
370
371 assert ' q1 is subset of q0: ' and q1.is_subset(q0) == False
372 print ' - ' * 30
373 assert ' q1 is subset of q1: ' and q1.is_subset(q1) == True
374 print ' - ' * 30
375 assert ' q1 is subset of q2: ' and q1.is_subset(q2) == True
376 print ' - ' * 30
377 assert ' q1 is subset of q3: ' and q1.is_subset(q3) == False
378 print ' - ' * 30
379 assert ' q1 is subset of q4: ' and q1.is_subset(q4) == False
380 print ' - ' * 30
381 print
382
383 assert ' q2 is subset of q0: ' and q2.is_subset(q0) == False
384 print ' - ' * 30
385 assert ' q2 is subset of q1: ' and q2.is_subset(q1) == False
386 print ' - ' * 30
387 assert ' q2 is subset of q2: ' and q2.is_subset(q2) == True
388 print ' - ' * 30
389 assert ' q2 is subset of q3: ' and q2.is_subset(q3) == False
390 print ' - ' * 30
391 assert ' q2 is subset of q4: ' and q2.is_subset(q4) == False
392 print ' - ' * 30
393 print
394
395 assert ' q3 is subset of q0: ' and q3.is_subset(q0) == False
396 print ' - ' * 30
397 assert ' q3 is subset of q1: ' and q3.is_subset(q1) == True
398 print ' - ' * 30
399 assert ' q3 is subset of q2: ' and q3.is_subset(q2) == True
400 print ' - ' * 30
401 assert ' q3 is subset of q3: ' and q3.is_subset(q3) == True
402 print ' - ' * 30
403 assert ' q3 is subset of q4: ' and q3.is_subset(q4) == False
404 print ' - ' * 30
405 print
406
407 assert ' q4 is subset of q0: ' and q4.is_subset(q0) == False
408 print ' - ' * 30
409 assert ' q4 is subset of q1: ' and q4.is_subset(q1) == True
410 print ' - ' * 30
411 assert ' q4 is subset of q2: ' and q4.is_subset(q2) == True
412 print ' - ' * 30
413 assert ' q4 is subset of q3: ' and q4.is_subset(q3) == False
414 print ' - ' * 30
415 assert ' q4 is subset of q4: ' and q4.is_subset(q4) == True
416 print ' - ' * 30
417

 

[参考]

百姓网那道题

2 《百姓网公开笔试题:查询条件的子集判断》的一份PHP答卷

3 从离散数学到编译原理--百姓网编程题后序

4 (How to Write a (Lisp) Interpreter (in Python))

转载于:https://www.cnblogs.com/emanonwzy/archive/2010/11/29/1891487.html

1- 安装lombok插件 ## mysql - 下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads - 下载后按提示进行安装 - 导入document/sql下的mall.sql文件 ## redis - 下载地址:https://github.com/MicrosoftArchive/redis/releases - 下载后按提示进行安装 ## OSS - 该项目文件上传采用OSS,需要自行注册OSS账号并配置 - 首先将mall-admin\src\main\resources\application.properties文件中以aliyun.oss.开头的配置改为你自己的配置 - OSS上传文件需要配置跨域资源共享(CORS)规则,参考文档:https://help.aliyun.com/document_detail/31928.html - 上传方式采用服务端签名后直传的形式,参考文档:https://help.aliyun.com/document_detail/31926.html ## mall-admin - 启动项目:直接运行com.macro.mall.MallAdminApplication的main方法即可 - 接口文档地址:http://localhost:8080/swagger-ui.html ## mall-search - 启动项目:直接运行com.macro.mall.search.MallSearchApplication的main方法即可 - 接口文档地址:http://localhost:8081/swagger-ui.html - 使用前需要先调用接口导入数据;http://localhost:8081/esProduct/importAll - 如出现无法启动的问题,可以先删除elasticsearch里面的数据再启动 ## mall-portal - 启动mall-portal项目:直接运行com.macro.mall.portal.MallPortalApplication的main方法即可 - 接口文档地址:http://localhost:8085/swagger-ui.html 1. 本地安装开发环境中的所有工具并启动 2. 克隆源代码到本地,使用IDEA或Eclipse打开,并完成编译; 3. 安装 redis mysql 4. 在mysql中新建mall数据库,导入document/sql下的mall.sql文件; 5. 启动mall-admin项目:直接运行com.macro.mall.MallAdminApplication的main方法即可, 接口文档地址:http://localhost:8080/swagger-ui.html;  6. 启动mall-portal项目:直接运行com.macro.mall.portal.MallPortalApplication的main方法即可, 接口文档地址:http://localhost:8085/swagger-ui.html;  7. 克隆mall-admin-web项目,并导入到IDEA中并完成编译传送门,需要安装node环境,然后到项目下; 8. 运行命令:npm install 然后执行 npm run dev,访问地址:http://localhost:8090 即可打开后台管理系统页面; 9. 克隆Mall-Vue-master项目,并导入到IDEA中并完成编译传送门; 10. 运行命令:npm run dev,访问地址: 即可打开pc商城页面; 11. 克隆vue-jd-master项目,并导入到IDEA中并完成编译传送门; 12. 运行命令:npm run dev,访问地址: 即可打开h5商城页面; 13. 下载小程序 用微信开发工具打卡就可以访问   https://gitee.com/zscat-platform/mall   功能预览   http://www.yjlive.cn:8090/#/home   https://gitee.com/zscat-platform/mall/wikis/pages 645
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值