预聚合分桶标签:多场所同标的的规范化分组编号
Pre-Aggregation Bucket Labels: Canonical-Form Group IDs for Multi-Venue Symbols
开始编码实现 solution(raw_symbols: list[str]) -> list[int]。对每条原始 symbol,按以下顺序计算它的规范形式:(1) 去掉前后 ASCII 空白(仅 ' ' 与 '\t');(2) 从第一个 . 起截断(含其后所有字符全部丢弃);(3) 仅对 ASCII 字母做大写(数字以及其他 ASCII 字符保持原样);(4) 结果若为空、长度 > 5、或含非 A-Z 字母 / 非 0-9 数字的字符,则视为无效。然后按首次出现顺序分配组编号:第一个出现的有效规范形式拿到 0,下一个新的有效规范形式拿到 1,依此类推。无效行写哨兵 -1 且不消耗组编号。返回与 raw_symbols 等长的整数列表。
例:solution(["ABC.V1", "abc.V2", "ZZA", "ABC", "QZA.X"]) 返回 [0, 0, 1, 0, 2]。下标 0、1、3 三行经截断+大写+校验后均归约到 "ABC"(组 0),下标 2 的 "ZZA" 引入组 1,下标 4 的 "QZA.X" 截断为 "QZA" 引入组 2。
需要明确的细节:空数组返回 [];去空白再截断后变空的行(如 ".US" 或 " ")无效,写 -1;去空白再截断后过长的行(如 "abcdef.X" -> "ABCDEF")无效;body 内含 '-'、'_'、' ' 等字符也会破坏有效性。顺序很重要:先去空白、再在第一个 '.' 截断、再大写、最后做校验。
朴素做法对每个字符串逐字符扫描(禁用 regex 库),同时维护一个 canonical_form -> 组编号的字典;总扫描开销为 O(N*L),其中 L <= 32。
实现细节由 stubs/stub.py 提供。
实践背景
多场所做市的撮合台经常会收到带场所代码后缀的同一虚拟标的("ABC.V1"、"ABC.V2")、CSV 管道带来的尾部空白、或不同经纪商口径下的混合大小写;任何预聚合环节(同标的成交合并、持仓滚动、盘后 TCA 分桶)都要先把这些行合并到稳定的"同一标的"桶里。返回按首次出现顺序的组编号——而不是字典序或哈希标签——是有意为之:下游报表的行会按当天报盘里不同标的的首次出现顺序渲染,故同一份输入重放可得到一致的行序和便于 diff 的输出。-1 哨兵把明显畸形的行(被截断的 symbol、超长杂串、嵌入分隔符的怪行)路由到隔离桶,不会中断扫描,让当天其余成交仍能正常聚合,同时把异常交给运维去查。
约束条件
- 0 <= len(raw_symbols) <= 4000
- 每个 raw_symbols[i] 是长度 <= 32 的 ASCII 字符串
- 经四步规范化后,若结果为空、或长度 > 5、或含 [A-Z0-9] 之外的字符,则该规范形式无效
- 无效输入映射到 -1(哨兵);有效形式按首次出现顺序拿到 0, 1, 2, ... 的连续编号
- 输出为与 raw_symbols 等长的 list[int],使用精确比对
样例
Case 1 · statement-example: venue suffix and case fold collapse to same group
输入: [["ABC.V1","abc.V2","ZZA","ABC","QZA.X"]]
期望: [0,0,1,0,2]
"ABC.V1"、"abc.V2"、"ABC" 在去尾缀+大写后均规范化为 "ABC",分到组 0;"ZZA" 是新形式分到组 1;"QZA.X" 规范化为 "QZA" 分到组 2。结果为 [0, 0, 1, 0, 2]。
Case 2 · visible: invalid (length > 5) gets sentinel -1
输入: [["ABCDEF","ABC","abcdef.X","ABC.V1"]]
期望: [-1,0,-1,0]
"ABCDEF" 长度为 6 超过 5,无效,得 -1;"ABC" 是首个有效规范形式,组 0;"abcdef.X" 在第一个 '.' 截断后为 "abcdef" 大写为 "ABCDEF",长度 6,无效,得 -1;"ABC.V1" 规范化为 "ABC",仍是组 0。结果 [-1, 0, -1, 0]。
Case 3 · visible: whitespace strip and empty after dot
输入: [[" ABC ","\tZZA\t",".US","","ABC"]]
期望: [0,1,-1,-1,0]
" ABC " 去掉空白后规范为 "ABC",组 0;"\tZZA\t" 去 tab 后为 "ZZA",组 1;".US" 在第一个 '.' 截断后为空,无效,-1;"" 直接为空,无效,-1;"ABC" 重复 "ABC",组 0。结果 [0, 1, -1, -1, 0]。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: venue suffix and case fold collapse to same group
输入: [["ABC.V1","abc.V2","ZZA","ABC","QZA.X"]]
期望: [0,0,1,0,2]
"ABC.V1"、"abc.V2"、"ABC" 在去尾缀+大写后均规范化为 "ABC",分到组 0;"ZZA" 是新形式分到组 1;"QZA.X" 规范化为 "QZA" 分到组 2。结果为 [0, 0, 1, 0, 2]。
Case 2 · visible: invalid (length > 5) gets sentinel -1
输入: [["ABCDEF","ABC","abcdef.X","ABC.V1"]]
期望: [-1,0,-1,0]
"ABCDEF" 长度为 6 超过 5,无效,得 -1;"ABC" 是首个有效规范形式,组 0;"abcdef.X" 在第一个 '.' 截断后为 "abcdef" 大写为 "ABCDEF",长度 6,无效,得 -1;"ABC.V1" 规范化为 "ABC",仍是组 0。结果 [-1, 0, -1, 0]。
Case 3 · visible: whitespace strip and empty after dot
输入: [[" ABC ","\tZZA\t",".US","","ABC"]]
期望: [0,1,-1,-1,0]
" ABC " 去掉空白后规范为 "ABC",组 0;"\tZZA\t" 去 tab 后为 "ZZA",组 1;".US" 在第一个 '.' 截断后为空,无效,-1;"" 直接为空,无效,-1;"ABC" 重复 "ABC",组 0。结果 [0, 1, -1, -1, 0]。