← 返回编程题库
coding-bitmask-position-flags简单免费版2000ms未尝试

持仓属性位掩码查询

Per-Position Flag Bitmask Queries

开始编码

交易台的持仓管理系统把每个持仓的属性 flag 编码为一个 32 位无符号整数的各个 bit:例如 bit 0 = "已对冲",bit 1 = "在限制名单",bit 2 = "自动展期",bit 3 = "受卖空约束"……最多 32 个独立属性。把 32 个 bool 压成一个 int 而不是 32 键的 dict 是常用做法,因为:(a) 内存占用约 8 倍更紧凑;(b) 集合包含查询塌缩为一次按位与;(c) 下游消费者(风控引擎、blotter、审计日志)只需序列化一个整数。

请实现 solution(positions, queries)positions(pos_id: str, flag_mask: int) 二元组列表,构建查找表;同名 pos_id 多次出现时,最后一次胜出(即写 dict 的自然语义)。queries(pos_id: str, op: str, mask: int) 三元组列表,对每条查询,先查到该持仓的 mask pm,再按 op 计算:

  • op == "has_all"boolmask 的每一位是否都在 pm 中?公式 (pm & mask) == mask
  • op == "has_any"boolpmmask 是否有至少一位重叠?公式 (pm & mask) != 0
  • op == "has_none"boolpmmask 是否完全不相交?公式 (pm & mask) == 0
  • op == "count_set"int:交集中有多少个置位?公式 bin(pm & mask).count("1")

两条硬性规则:(1) 若 pos_id 不在表中,该查询结果为 None——不抛异常,也不退化为 False0;(2) 若 op 不在四个允许值之内,抛 ValueError

示例

solution([("P1", 5), ("P2", 6)], [("P1", "has_all", 5), ("P1", "has_any", 8), ("P2", "has_none", 1), ("P2", "count_set", 7)]) 返回 [True, False, True, 2]。逐条验证:P1 = 5 = 0b0101(置位 {0, 2});P2 = 6 = 0b0110(置位 {1, 2})。has_all 55 & 5 == 5 → True。has_any 8 = 0b10005 & 8 == 0 → False(P1 没有 bit 3)。has_none 16 & 1 == 0 → True(P2 没有 bit 0)。count_set 7 = 0b1116 & 7 = 6 = 0b110 → 2 个置位。

solution([], [("X", "has_all", 1), ("Y", "count_set", 255)]) 返回 [None, None]——空 positions 表导致每次查找都 miss,函数因为缺 key 而抛异常。

solution([("P", 1), ("P", 2), ("P", 4)], [("P", "has_all", 4)]) 返回 [True]。三次对 P 的写入按顺序发生,最后一次(mask = 4)胜出;4 & 4 == 4

函数骨架见 stubs/stub.py

应用背景

位掩码 flag 是交易系统里紧凑存属性最常用的结构。持仓服务通常持有 ~10⁵ 个活仓、每个有 16–32 个布尔属性;用一个 uint32 编码整个 flag 表只需 ~400 KB,而 dict-of-dicts 要 30+ MB——当服务在数百个风控引擎节点上副本运行、且每次重发布都从快照热启动时,这点差距非常关键。查询操作直接对应常见看板:has_all 实现「同时已对冲且在 watchlist 上的持仓」(交集筛选);has_any 实现「有任意监管 flag 的持仓」(合规广播);has_none 是其否定形式(「干净的持仓」);count_set 回答「这个持仓通过了几条审计检查」——一次 popcount 替代 N 次分支。「找不到 pos_id 返回 None」的契约是标准的幂等读:UI 缓存可能查到刚刚被平仓清出的持仓,正确的行为是把那一行置灰,而不是崩掉整个请求。

约束条件

  • 0 ≤ len(positions) ≤ 10000
  • 0 ≤ len(queries) ≤ 10000
  • 0 ≤ flag_mask, mask < 2**32(无符号 32 位范围内)
  • pos_id 为字母数字,长度 ≤ 16,区分大小写
  • op ∈ {'has_all', 'has_any', 'has_none', 'count_set'},否则抛 ValueError
  • 若 pos_id 不在 positions 表里,该 query 结果为 None(不抛异常)
  • 若 pos_id 在 positions 中重复出现,最后一次写入胜出

样例

Case 1 · canonical statement example — all four ops

输入: [[["P1",5],["P2",6]],[["P1","has_all",5],["P1","has_any",8],["P2","has_none",1],["P2","count_set",7]]]

期望: [true,false,true,2]

P1=5=0b0101 (置位{0,2}),P2=6=0b0110 (置位{1,2})。has_all 5: 5&5=5==5 → True。has_any 8=0b1000: 5&8=0 → False (bit 3 在 P1 里未置)。has_none 1: 6&1=0 → True (bit 0 在 P2 里未置)。count_set 7=0b111: 6&7=6=0b110 → 2 个置位。

Case 2 · empty positions — every query returns None

输入: [[],[["X","has_all",1],["Y","count_set",255]]]

期望: [null,null]

positions 为空时,任何查询的 pos_id 都查不到,返回 None 而不是抛异常。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · canonical statement example — all four ops

输入: [[["P1",5],["P2",6]],[["P1","has_all",5],["P1","has_any",8],["P2","has_none",1],["P2","count_set",7]]]

期望: [true,false,true,2]

P1=5=0b0101 (置位{0,2}),P2=6=0b0110 (置位{1,2})。has_all 5: 5&5=5==5 → True。has_any 8=0b1000: 5&8=0 → False (bit 3 在 P1 里未置)。has_none 1: 6&1=0 → True (bit 0 在 P2 里未置)。count_set 7=0b111: 6&7=6=0b110 → 2 个置位。

Case 2 · empty positions — every query returns None

输入: [[],[["X","has_all",1],["Y","count_set",255]]]

期望: [null,null]

positions 为空时,任何查询的 pos_id 都查不到,返回 None 而不是抛异常。