如何解决如何将单词列表读入包含单词位置的元组?
我有一个文本文件,我想编写一个函数来读取这个文件并返回一个元组列表,其中每个元组将包含作为字符串的单词、作为 int 的单词行号以及单词的最后一个字符为 int。样本输入,
example of the first line
followed by the second line
示例输出:
[
("example",1,8);
("of",11);
("the",15);
("first",21);
("line",26);
("followed",2,13);
("by",16);
("the",20);
("second",27);
("line",32)
]
解决方法
你正在寻找的函数看起来像这样,
let read filename =
In_channel.read_lines filename |>
List.mapi ~f:(fun line data ->
String.split data ~on:' ' |>
List.fold_map ~init:0 ~f:(fun pos word ->
let pos = pos + String.length word in
pos+1,(word,line+1,pos-1)) |>
snd) |>
List.concat
这是如何使用它。先安装依赖,
opam install dune stdio merlin
接下来,设置您的项目,
dune init exe readlines --libs=base,stdio
然后在您喜欢的编辑器中打开 readlines.ml
并将其内容替换为以下内容,
open Base
open Stdio
let read filename =
In_channel.read_lines filename |>
List.mapi ~f:(fun line data ->
String.split data ~on:' ' |>
List.fold_map ~init:0 ~f:(fun pos word ->
let pos = pos + String.length word in
pos+1,pos-1)) |>
snd) |>
List.concat
let print =
List.iter ~f:(fun (line,data,pos) ->
printf "(%s,%d,%d)\n" line data pos)
let main filename =
print (read filename)
let () = match Sys.get_argv () with
| [|_; filename|] -> main filename
| _ -> failwith "expects one argument: filename"
要运行和测试,请创建一个示例输入,例如一个名为 test.txt
example of the first line
followed by the second line
(确保最后一行后跟一个换行符)
现在你可以运行它了,
dune exec ./readlines.exe test.txt
结果应该如下,
(example,1,6)
(of,9)
(the,13)
(first,19)
(line,24)
(followed,2,7)
(by,10)
(the,14)
(second,21)
(line,26)
(注意,我是从 0 而非 1 开始计算位置)。
您也可以在 utop 中以交互方式运行此代码,但您需要安装 base
和 stdio
并将它们加载到解释器中,使用
#require "base";;
#require "stdio";;
如果您使用的不是 utop
而是默认的 OCaml 顶层,您还需要安装 ocamlfind (opam install ocamlfind
) 并执行
#use "topfind";;
#require "base";;
#require "stdio";;
,
如果您只想将标准库用作字符串,您可以使用 class Product extends Model
{
/**
* The product point of contact (which is an user).
*/
public function pointOfContact()
{
return $this->belongsToMany(User::class,'product_point_of_contact');
}
}
以及在每一行上应用的其他一些东西来做您想做的事情。
这是一个关于如何处理第一留置权的例子
String.split_on_char
正如 ivg 所说,你可以用 let ic = open_in (*your file name*) in
let first_line = input_line ic in
let words = String.split_on_char ' ' first_line in
let rec aux accLen =
function
| [] -> []
| s :: ts ->
match s with
(* empty string means that their were a white space before the split *)
| "" -> aux (accLen +1) ts
| s -> let l = accLen + String.length s in (1,s,l) :: aux l ts
in aux 0 words;;
替换 aux 函数:
List.fold_left
,
不包括文件 I/O 组件,但可以正确处理单词之间的多个空格,包括制表符。一些有趣的 .equals()
用法来娱乐新的 OCaml 程序员。
fold_left
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。