← 返回编程题库
coding-canonical-symbol-group-ids中等免费版2000ms未尝试

预聚合分桶标签:多场所同标的的规范化分组编号

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 可见样例;服务端提交会运行可见样例和隐藏测试。

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

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

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]。