OCaml交换列表中的元素

时间:2016-02-20 13:39:42

标签: ocaml

我正在尝试交换列表中的两个元素,但不确定为什么地雷无效。

正确的实施应该做到以下几点:

list_swap_val [5;6;7;3] 75 => [7;6;5;3] 
list_swap_val [5;6;3] 7 5 => [7;6;3] 

这是我尝试过的两种不同的实现,但两者似乎只是返回原始列表

let rec list_swap l u v =
    match l with
   |[] -> []
   |h::t -> if h = u then u::(list_swap t u v)
            else if h = v then v::(list_swap t u v)
            else h::(list_swap t u v) ;;

我也试过上面但是在匹配语句中使用while而不是使用if,但两者都不起作用。我哪里错了?谢谢你的帮助

3 个答案:

答案 0 :(得分:4)

您忘记实际交换值:当您看到u时,返回列表的第一个元素应为v。在这里,它就像在所有情况下构建h::(list_swap t u v)一样。 顺便说一下,你可以对递归调用进行分解,最后给出了这个定义:

let rec list_swap l u v =
  match l with
    | [] -> []
    | h::t -> (if h = u then v 
                else if h = v then u 
                  else h)::(list_swap t u v);;

答案 1 :(得分:4)

正如coredump所写,你可以将它分解,但你可以更进一步,注意这是一张地图。

let swap u v x = if x = u then v else if x = v then u else x
let list_swap u v = List.map (swap u v)

答案 2 :(得分:1)

如上所述,你忘记了交换。您也可以使用List.map:

public interface VendorRepository extends Repository<Vendor, Long> {

@Cacheable("vendorByUsername")
Vendor getVendorByUsername(String username);

@CacheEvict(value = {"vendorByUsername", "vendor", "vendors"}, allEntries = true)
Vendor save(Vendor vendor);

@Cacheable("vendor")
Vendor findOne(Long id);

@Cacheable("vendors")
List<Vendor> findAll();
}

这会调用函数&#34; swap u v&#34; (感谢部分评估)列表中的每个元素&#34; l&#34;。

然而,这隐藏了递归调用,你应该知道map不是尾递归的。如果你想使用map并有尾递归:

let swap u v n = match n with
     |x when x = u -> v
     |x when x = v -> u
     |_ -> n;;
let list_swap l u v = List.map (swap u v) l;;

&#34; rev_map&#34;与&#34; map&#34;相同除了它同时反转列表,它是尾递归。所以你之后再次反转列表。 &#34;转&#34;也是尾递归!