【发布时间】:2016-11-23 19:16:23
【问题描述】:
前段时间,我决定在 HackerRank 上解决一个简单的任务,但使用 OCaml 和 Core 来学习它们。在其中一项任务中,我应该从标准输入中读取数据:
第一行包含一个整数,表示条目数 在电话簿中。随后的每一行都描述了一个条目 单行上的空格分隔值的形式。第一个值 是朋友的名字,第二个值是 -digit 电话号码。
在电话簿条目的行之后,有一个未知数量的 查询行。每行(查询)都包含一个要查找的内容,而您 必须继续读取行,直到没有更多输入为止。
主要问题:
- 不知道会有多少行
- 最后一行不以换行符结尾,所以在
End_of_file之前我不能只阅读scanf "%s\n"
然后我的代码变得乱七八糟:
open Core.Std
open Printf
open Scanf
let read_numbers n =
let phone_book = String.Table.create () ~size:n in
for i = 0 to (n - 1) do
match In_channel.input_line stdin with
| Some line -> (
match (String.split line ~on:' ') with
| key :: data :: _ -> Hashtbl.set phone_book ~key ~data
| _ -> failwith "This shouldn't happen"
)
| None -> failwith "This shouldn't happen"
done;
phone_book
let () =
let rec loop phone_book =
match In_channel.input_line stdin with
| Some line -> (
let s = match Hashtbl.find phone_book line with
| Some number -> sprintf "%s=%s" line number
| None -> "Not found"
in
printf "%s\n%!" s;
loop phone_book
)
| None -> ()
in
match In_channel.input_line stdin with
| Some n -> (
let phone_book = read_numbers (int_of_string n) in
loop phone_book
)
| None -> failwith "This shouldn't happen"
如果我用 Python 解决这个任务,那么代码如下所示:
n = int(input())
book = dict([tuple(input().split(' ')) for _ in range(n)])
while True:
try:
name = input()
except EOFError:
break
else:
if name in book:
print('{}={}'.format(name, book[name]))
else:
print('Not found')
这比 OCaml 代码更短更清晰。关于如何改进我的 OCaml 代码的任何建议?还有两件重要的事情:我不想放弃 OCaml,我只想学习它;第二——出于同样的原因,我想使用 Core。
【问题讨论】:
标签: ocaml