OCaml如何将含空格的字符列表分割为子列表?
OCaml 字符列表按空格分组实现方案
问题说明
你当前的代码les_nb仅能过滤掉所有空格,返回扁平化的无空格字符列表,但无法将原列表按空格分割为连续数字组成的子列表(忽略连续空格,不生成空列表)。目标是将['1'; '2'; '3'; ' '; ' '; '4'; '5'; ' '; '6']转换为[['1';'2';'3']; ['4';'5']; ['6']]。
实现思路
核心逻辑是遍历原列表,维护两个状态:
- 当前正在构建的数字子列表
- 已完成分组的结果列表
遍历过程中:
- 遇到数字字符时,将其加入当前子列表
- 遇到空格时,若当前子列表不为空,则将其加入结果列表,并重置当前子列表为空;若当前子列表为空(连续空格),则直接跳过
- 遍历结束后,需检查当前子列表是否为空,若非空则加入结果列表(处理末尾无空格的数字组)
代码实现
基础版本(直观易懂)
type chiffre = int (*0-9*);; type chiffreCar = char (* '0' - '9'*) type nombre = chiffre list;; type txtnb = chiffreCar list ;; let split_into_numbers (lst: txtnb) : txtnb list = let rec helper remaining current result = match remaining with | [] -> (* 处理最后一个非空数字组 *) if current = [] then result else result @ [current] | ' ' :: tl -> (* 遇到空格时,若当前有数字组则加入结果 *) let new_result = if current = [] then result else result @ [current] in helper tl [] new_result | hd :: tl -> (* 将数字字符加入当前组 *) helper tl (current @ [hd]) result in helper lst [] []
优化版本(高效处理长列表)
上述基础版本使用@操作符拼接列表,对于长列表效率较低。以下版本通过反向构建列表并最终反转的方式提升性能:
let split_into_numbers_optimized (lst: txtnb) : txtnb list = let rec helper remaining current_rev result = match remaining with | [] -> (* 反转最后一个数字组并加入结果,再整体反转得到正确顺序 *) let final_result = if current_rev = [] then result else (List.rev current_rev) :: result in List.rev final_result | ' ' :: tl -> let new_result = if current_rev = [] then result else (List.rev current_rev) :: result in helper tl [] new_result | hd :: tl -> (* 反向构建当前数字组(前置操作效率更高) *) helper tl (hd :: current_rev) result in helper lst [] []
测试示例
let test_input = ['1'; '2'; '3'; ' '; ' '; '4'; '5'; ' '; '6'];; split_into_numbers test_input;; (* 输出: [['1'; '2'; '3']; ['4'; '5']; ['6']] *) split_into_numbers_optimized test_input;; (* 输出同上 *)
边缘情况处理
- 空列表:
split_into_numbers []返回[] - 开头含空格:
split_into_numbers [' '; '1'; '2']返回[['1'; '2']] - 结尾含空格:
split_into_numbers ['1'; '2'; ' ']返回[['1'; '2']] - 全空格:
split_into_numbers [' '; ' ']返回[]
内容的提问来源于stack exchange,提问作者Batu
相关产品推荐
相关产品推荐

