x是列表,v是列表中的元素。需要返回该元素的索引,v else应该返回-1。
当元素在列表中时,下面的代码工作正常,但是在找不到时它不会返回-1。
错误是else let j = 1+index t v in j
,因为它一直加1,当传递空列表时它会total = total - 1
,从而返回最后一个元素的索引。
我是一名新的OCaml学员,不知道如何解决这个问题。
let rec index x v =
match x with
[] -> -1
| h::t ->
if h == v then 0
else let j = 1+ index t v in j
答案 0 :(得分:2)
首先,您可以直接说else 1 + index t v
而不是else let j ...
其次,只要所需的元素确实存在于列表中,代码的逻辑就没有错,正如你所说的那样。随着迭代的继续,你基本上会继续增加一个。
但是,很难处理元素不在列表中的情况,因为先前的计数不会被停止。
为了解决这个问题,最好将计数保留在我们自己的手中,所以如果没有找到但仍然在列表的中间,那么增加计数;如果找到,则返回计数;如果没有找到并到达终点,则返回-1,而不是计数。
因此,count必须是我们的递归函数的参数。
let index v l =
let rec aux c = function
| [] -> None
| h::t ->
if h = v then Some c
else aux (c+1) t
in
aux 0 l
上述逻辑恰好转换为尾递归(迟早你会学习)。
p.s。,通常你使用h = v
,因为它是值检查。 h == v
是一次物理平等检查,通常我们不想这样做。