我正在尝试在编码问题网站上运行以下代码,它说存在运行时错误,但在顶级 ocaml 上运行它似乎工作正常。代码中是否有任何错误来源?提前致谢
问题是在给定的列表中找到“好段”的数量和一个特定的数字。一个好的段定义如下:
以下是输入。
输出应该是打印出来的单个数字。
let rec drop_value l to_drop =
match l with
| [] -> []
| hd :: tl ->
let new_tl = drop_value tl to_drop in
if hd = to_drop then new_tl else hd :: new_tl
;;
let rec find_start li t cur_min =
match li with
| [] -> cur_min
| hd :: tl -> let new_min = abs (t - hd) in
if new_min = 0 then find_start tl t new_min
else if new_min < cur_min && t > hd then find_start tl t new_min
else find_start tl t cur_min
;;
let rec find_end li t cur_min =
match li with
| [] -> cur_min
| hd :: tl -> let new_min = abs (t - hd) in
if new_min = 0 then find_end tl t new_min
else if new_min < cur_min && t < hd then find_end tl t new_min
else find_end tl t cur_min
;;
let rec contains_value l value =
match l with
| [] -> false
| hd :: tl -> if hd = value then true else contains_value tl value
;;
let nums = ref [];;
let n = read_int () in
for i = 1 to n do
Scanf.scanf " %d" (fun a ->
nums := a :: !nums)
done;
Scanf.scanf " %d" (fun t ->
if contains_value !nums t then print_int 0
else let start = if List.length !nums = 1 then 1 else abs (find_start !nums t 1001 - t) in
let finish = find_end (drop_value !nums start) t 1001 + t in
if t > start && t < finish then (if start = 1 && List.length ! nums = 1 then print_int ((t - start + 1) * (finish - t) - 1) else print_int ((t - start) * (finish - t) - 1))
else let start = 1 in print_int ((t - start + 1) * (finish - t) - 1))
;;
例如
5
4 8 13 24 30
10
应该给
5
=> [9, 10], [9, 11], [9, 12], [10, 11], [10, 12]
答案 0 :(得分:1)
您没有描述您的代码将获得的确切输入格式。这使得调试代码几乎不可能。
当我使用您描述的输入编译并运行您的代码(如 m.ml
)时,我看到:
$ ./m
5 4 8 13 24 30 10
Fatal error: exception Failure("int_of_string")
事实上,无论我尝试输入什么格式,我都会得到相同的结果。
这可能就是网站上正在发生的事情。
根据我的经验,使用 scanf
总是弊大于利。将其与其他输入函数结合使用可能会使情况变得更糟。
如果您仔细描述了输入的预期格式,StackOverflow 上的某个人可以推荐一种获取数字的方法。
与此同时,这里有一种方法可以读取一行中的所有数字:
let rec split_at list n =
if n = 0 then
([], list)
else
match list with
| [] -> ([], [])
| h :: t ->
let (a, b) = split_at t (n - 1) in (h :: a, b)
in
let (nums, t) =
let line = read_line () in
let nstrs = Str.split (Str.regexp "[ \t][ \t]*") line in
match List.map int_of_string nstrs with
| [] -> failwith "no numbers"
| n :: rest ->
if List.length rest <> n + 1 then
failwith "bad count"
else
let (nums, tlist) = split_at rest n in
(nums, List.hd tlist)
in
. . .