字符串到字符列表

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

我想编写一个函数,它接受一个字符串并返回一个字符列表。这是一个函数,但我认为它不是我想要的(我想获取一个字符串并返回一个字符列表)。

let rec string_to_char_list s =
    match s with
      | "" -> []
      | n -> string_to_char_list n
ocaml
7个回答
31
投票

除此之外,但非常重要:

您的代码显然是错误的,因为您有一个递归调用,其中所有参数都与您输入的参数完全相同。它将引发无限序列的具有相同值的调用,从而永远循环(堆栈溢出获胜)在尾部记录位置不会发生)。


执行您想要的操作的代码是:

let explode s =
  let rec exp i l =
    if i < 0 then l else exp (i - 1) (s.[i] :: l) in
  exp (String.length s - 1) []

来源: http://caml.inria.fr/pub/old_caml_site/FAQ/FAQ_EXPERT-eng.html#strings


或者,您可以选择使用库:battery String.to_list 或 extlib String.explode


28
投票

试试这个:

let explode s = List.init (String.length s) (String.get s)

6
投票

又好又简单:

let rec list_car ch = 
  match ch with
  | "" -> []
  | ch -> String.get ch 0 :: list_car (String.sub ch 1 (String.length ch - 1));;

5
投票

从 OCaml 4.07 (2018 年发布) 开始,这可以通过 序列 直接完成。

let string_to_char_list s =
  s |> String.to_seq |> List.of_seq

查看为字符串创建序列的实现可能会有所帮助。在标准库中,这是通过字节类型完成的,但我们可以实现一个简单的函数来直接对字符串执行相同的操作。

let string_to_seq s =
  let rec aux i () =
    if i = String.length s then Seq.Nil
    else Seq.Cons (s.[i], aux @@ i + 1)
  in
  aux 0

或者使用异常:

let string_to_seq s =
  let rec aux i () =
    match String.get s i with
    | ch -> Seq.Cons (ch, aux @@ i + 1)
    | exception Invalid_argument _ -> Seq.Nil
  in
  aux 0

如果我们提供一个默认值为

0
的起始索引参数,我们就可以避免嵌套的内部函数。

let rec string_to_seq ?(i=0) s () =
  match String.get s i with
  | ch -> Seq.Cons (ch, string_to_seq ~i: (i+1) s)
  | exception Invalid_argument _ -> Seq.Nil

这让我们可以简单地调用

string_to_seq "hello world"
,但也可以指定一个大于
0
的初始启动序列。


3
投票

这样的事情怎么样:

let string_to_list str =
  let rec loop i limit =
    if i = limit then []
    else (String.get str i) :: (loop (i + 1) limit)
  in
  loop 0 (String.length str);;

let list_to_string s =
  let rec loop s n =
    match s with
      [] -> String.make n '?'
    | car :: cdr ->
       let result = loop cdr (n + 1) in
       String.set result n car;
       result
  in
  loop s 0;;

1
投票

这是从字符串中获取字符列表的迭代版本:

let string_to_list s = 
  let l = ref [] in
  for i = 0 to String.length s - 1 do
    l := (!l) @ [s.[i]]
  done;
  !l;;

1
投票

我的代码,适合现代 OCaml:

let charlist_of_string s =
  let rec trav l i =
    if i = l then [] else s.[i]::trav l (i+1)
  in
  trav (String.length s) 0;;

let rec string_of_charlist l =
  match l with
    [] -> "" 
  | h::t -> String.make 1 h ^ string_of_charlist t;;
© www.soinside.com 2019 - 2024. All rights reserved.