如何将这个int列表列表转换为包含+和*的数学表达式?



给定这个列表:

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 

我想提出另一个解决方案,使用字符串更短。concat和List。Concat(如有必要).

我"idea"是使用

String.concat "+" mylist

让它变成"像这样:

[[1;2;3]+[4]+[5]+[6]+[7]+[8;9]]

,然后调用String.concat "*" on the inner list of length >=2所以我得到这个:

[[1*2*3]+[4]+[5]+[6]+[7]+[8*9]]

和列表。连接得到1*2*3+4+5+6+7+8*9但这不是怎么串的。concat工作,所以我不确定如何实现这个

编辑:NEW SOLUTION

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 test)))
(* STEP BY STEP *)
(* [[1; 2; 3]; [4]; [5]; [6]; [7]; [8; 9]] *)
(convertListToString mylist)
(* string list list =
[["1"; "2"; "3"]; ["4"]; ["5"]; ["10"; "11"]; ["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 (List.map (fun x -> [String.concat "*" x ]) (convertListToString mylist)));;
(* string list = ["1*2*3"; "4"; "5"; "6"; "7"; "8*9"] *)
String.concat "+" (List.concat (List.map (fun x -> [String.concat "*" x ]) (convertListToString mylist)))
(* string = "1*2*3+4+5+6+7+8*9" *)

编辑2:NEW SOLUTION

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)

打印复杂数据类型的一种可能性是使用Format模块它有一个内置的组合子pp_print_list,用于为打印机中的元素列表创建一个打印机。

(* Format names are a bit too verbose *)
let int, list = Format.(pp_print_int, pp_print_list)
(* The separator will be either "+" or "*" *) 
let const x ppf () = Format.fprintf ppf x
let factor ppf l = 
(* a factor is a list of int separated by a "*" *)
list ~pp_sep:(const "*") int ppf l
let expr ppf l =
(*an expression is a list of factors separated by "+"*) 
list ~pp_sep:(const "+") factor ppf l

那么可以使用Format.asprintf从这个打印机构建一个字符串:

let s = Format.asprintf "%a" expr [[1;2;3];[4];[5];[6];[7];[8;9]]

假设您有一个函数soi,它将整型转换为字符串。然后,您可以使用List.map将该函数映射到int型列表上,从而将int型列表更改为字符串列表。这样,你就有了一个函数,可以将int型列表更改为字符串列表。

如果你将这个函数与String.concat组合在一起,你就得到了一个将整型列表转换为字符串的函数。(您可以使用"+"作为分隔符。)

如果你将这个函数映射到你的原始输入上,你最终会得到一个字符串列表。

那么你就有了一个函数,可以将int类型的list的列表变为string类型的列表。

如果您将此函数与String.concat组合在一起,您将得到一个字符串。(可以使用"*"作为分隔符)

您可以使用String.concat连接字符串和List.map将列表更改为字符串列表:

let mylist = [[1;2;3];[4];[5];[6];[7];[8;9]];;
let f xs =
String.concat
"+" 
(List.map 
(fun x -> String.concat
"*" 
(List.map (fun i -> string_of_int i) x))
xs);;
# f mylist;;
- : string = "1*2*3+4+5+6+7+8*9"

你也可以用一些高阶的辅助函数来写:

let mylist = [[1;2;3];[4];[5];[6];[7];[8;9]]
let convcat sep conv xs = String.concat sep (List.map conv xs)
let convplus = convcat "+" string_of_int
let convmul = convcat "*" convplus  
let res = convmul mylist;;
val mylist : int list list = [[1; 2; 3]; [4]; [5]; [6]; [7]; [8; 9]]
val convcat : string -> ('a -> string) -> 'a list -> string = <fun>
val convplus : int list -> string = <fun>
val convmul : int list list -> string = <fun>
val res : string = "1+2+3*4*5*6*7*8+9"

最新更新