Ocaml 将字符串转换为元组列表

问题描述 投票:0回答:2

我有文件“example.dat”,其中包含文本

"[(1,2); (3,4); (5,6)]"
。我需要从中获取元组列表。我知道,如何从整数列表中获取它。

# let f line = List.map int_of_string line;;
# open Printf
      let file = "example.dat"  
      let () =
      let ic = open_in file in
        try 
          let line = input_line ic in        
  f line;
  flush stdout;
        close_in ic
        with e ->
        close_in_noerr ic;
        raise e;;

我必须如何改变我的职能?

casting tuples ocaml
2个回答
0
投票

给定一个表示整数的字符串列表,您的函数

f
返回一个整数列表。它不返回元组列表。

您没有说明是否要验证输入是否具有某种正确的形式。如果您想验证它是否具有(例如)OCaml 中类型

(int * int) list
的列表的形式,这是一个需要一些工作的解析问题。

如果您只想提取输入行中看起来像整数的部分,您可以使用

Str
模块中的正则表达式处理:

# let re = Str.regexp "[^0-9]+" in
  Str.split re "[(1,2); (37,4); (5,6)]";;
- : string list = ["1"; "2"; "37"; "4"; "5"; "6"]

然后你可以重写你的函数

f
以将每对整数收集到一个元组中。我没有找到使用
List.map
的好方法。您可能必须编写自己的递归函数或使用
List.fold_left

更新

我将为您编写一个函数,将值列表更改为对列表。我希望这不是学校作业,在这种情况下你应该自己解决这个问题。

let rec mkpairs l =
    match l with
    | [] | [_] -> []
    | a :: b :: rest -> (a, b) :: mkpairs rest

如您所见,如果列表有奇数个元素,则此函数会默默地丢弃列表的最后一个元素。

该函数不是尾递归。所以这是你可以考虑改进的地方。


0
投票
let parse_array_string array_string =
  let open Genlex in
  let open Stream in
  let lexer = make_lexer ["["; "("; ","; ")"; ";"; "]";] in
  let stream = lexer (of_string array_string) in
  let fail () = failwith "Malformed string" in
  let parse_tuple acc = 
    match next stream with
    | Int first -> ( 
        match next stream with
        | Kwd "," -> ( 
            match next stream with
            | Int second -> ( 
                match next stream with
                | Kwd ")" -> (first, second) :: acc
                | _ -> fail () 
              )
            | _ -> fail () 
          )
        | _ -> fail () 
      )
    | _ -> fail ()
    in
    let rec parse_array acc =
      match next stream with
      | Kwd "(" -> parse_array (parse_tuple acc)
      | Kwd ";" -> parse_array acc
      | Kwd "]" -> acc
      | _ -> fail ()
    in
    try
      match next stream with
      | Kwd "[" -> List.rev (parse_array [])
      | _ -> fail ()
    with Stream.Failure -> fail ();;
© www.soinside.com 2019 - 2024. All rights reserved.