OCaml如何将嵌套整型列表转换为含+*的数学表达式
OCaml嵌套列表转指定格式字符串实现
需求说明
给定如下嵌套整数列表:
let mylist = [[1;2;3];[4];[5];[6];[7];[8;9]]
需要将其转换为如下格式的字符串:"1*2*3+4+5+6+7+8*9"
转换规则:
- 内层列表的元素用
*连接 - 各个内层列表处理后的结果用
+连接
初始递归实现
最初手写的递归实现代码如下:
let rec printexpr = function | [] -> "" | [x] -> print_inner_list x | x::t -> print_inner_list x ^ "+" ^printexpr t and print_inner_list = function | [] -> "" | [x] -> string_of_int x | x::y -> string_of_int x ^ "*" ^ print_inner_list y
该方案可正常运行,但希望通过使用String.concat、必要时搭配List.concat,写出更简短的实现。
思路误区
最初设想直接调用String.concat "+" mylist,以为能得到类似[[1;2;3]+[4]+[5]+[6]+[7]+[8;9]]的中间结构,之后对长度≥2的内层列表调用String.concat "*",得到[[1*2*3]+[4]+[5]+[6]+[7]+[8*9]],最后通过List.concat得到目标结果。但实际String.concat的运行逻辑和该设想不符,无法直接按这个路径落地。
迭代实现
第一版可运行解法
首先实现了可正确输出结果的版本,代码如下:
let rec convertListToString = function | [] -> [] | x::y -> [List.map string_of_int x] @ convertListToString y let mylist = [[1;2;3];[4];[5];[6];[7];[8;9]] let _ = String.concat "+" (List.concat (List.map (fun x -> [String.concat "*" x ]) (convertListToString mylist)))
分步执行过程:
- 初始输入:
[[1; 2; 3]; [4]; [5]; [6]; [7]; [8; 9]] - 执行
convertListToString mylist,将所有整数转为字符串,输出类型为string list list,结果为[["1"; "2"; "3"]; ["4"]; ["5"]; ["6"]; ["7"]; ["8"; "9"]] - 执行
List.map (fun x -> [String.concat "*" x ]) (convertListToString mylist),将每个内层字符串列表用*连接成单个字符串,输出类型为string list list,结果为[["1*2*3"]; ["4"]; ["5"]; ["6"]; ["7"]; ["8*9"]] - 执行
List.concat将上述嵌套列表展平为一维字符串列表,输出类型为string list,结果为["1*2*3"; "4"; "5"; "6"; "7"; "8*9"] - 最后执行
String.concat "+"将一维列表的元素用+连接,得到最终结果:"1*2*3+4+5+6+7+8*9"
第二版精简解法
在第一版基础上优化,去掉冗余的List.concat包装逻辑,代码更简洁:
let rec convertListToString = function | [] -> [] | x::y -> string_of_int x :: convertListToString y let mylist = [[1;2;3];[4];[5];[10;11];[6];[7];[8;9]] let _ = String.concat "+" (List.map (fun x -> String.concat "*" (convertListToString x)) mylist)
该版本逻辑更直接:
- 先通过
convertListToString把单个内层整数列表转为字符串列表 - 对每个内层列表直接用
String.concat "*"连接成乘式字符串 - 最后把所有乘式字符串用
String.concat "+"连接,直接得到最终结果,不需要额外展平操作。
内容的提问来源于stack exchange,提问作者Satcha
相关产品推荐
相关产品推荐

