OCaml数据结构,用于查找最后一个元素

时间:2013-11-23 09:22:42

标签: data-structures ocaml

我正在寻找能够回答以下问题的数据结构? 列表中有多少元素低于当前元素。我想为列表中的每个元素计算它。此外,它必须是列表的一致子序列。

例如:

[1;2;3;-3;5;3]

正确答案是:

[0; 1; 2; 0; 4; 0]

2 个答案:

答案 0 :(得分:0)

我不确定我是否正确理解您的问题,因为您的'正确答案'似乎与您描述问题的方式不一致,但这里是解决所述问题的可能方法:

let xs = [1;2;3;-3;5;3] in 
let comp x y = 
    if (x < y) then -1
    else if (x > y) then 1
    else 0
in
let sorted_xs = List.sort comp xs in
let index x =
    let rec helper i xs =
        match xs with
        | [] -> failwith "Item not in list"
        | hd::tl -> (
            if (hd = x) then i
            else helper (i+1) tl
        )
    in helper 0 sorted_xs
in
List.map index xs

我不确定这是否正是你要解决的问题,但至少应该给你一般的想法。

这样的结果是[1; 2; 3; 0; 5; 3],这是列表中其他项目的数量低于该索引处的项目。

** * ** 更新 * ** * *

这是基于您在评论中描述的内容的正确代码。如果这是有道理的,请告诉我。

let xs = [1;2;3;-5;6;7;10;-1;4] in
let transfer_item xs1 xs2 =
   match xs1 with
   | [] -> failwith "Invalid list"
   | hd::tl -> (tl,hd::xs2)
in
let find_item xs i =
    let rec helper xs count =
        match xs with
        | [] -> count
        | hd::tl -> (
          if (hd > i) then count
          else helper tl (count+1)
        )
     in helper xs 0
in
let rec new_list xs ref_list =
    match xs with
    | [] -> []
    | hd::tl -> (
      let first = find_item ref_list hd in
      let (xs, ref_list) = transfer_item xs ref_list in
      first::(new_list xs ref_list)
    )
in new_list xs []

答案 1 :(得分:0)

您可以使用两个递归函数轻松解决您的问题:一个用于在列表中进行迭代,另一个用于检查列表中的前置函数。以下代码是一种可能的实现:

let rec countElementsLessThan list value =

    match list with

        | []           -> 0

        | head :: tail -> if head < value
                          then 1 + (countElementsLessThan tail value)
                          else countElementsLessThan tail value

;;

(*******************************)

let rec count remaining alreadySeen result =

    match remaining with

        | []           -> result

        | head :: tail -> let elementsLessThanHead = countElementsLessThan alreadySeen head in
                          count tail (head :: alreadySeen) (result @ [elementsLessThanHead])

;;

(*******************************)

let rec printList list =

    match list with

        | []           -> print_newline ()

        | head :: tail -> print_int head;
                          printList tail

;;

(*******************************)

let result = count [1;2;3;-3;5;3] [] [];;
printList result;;

此处,方法count将迭代并将已经看到的元素存储在名为alreadySeen的列表中。然后,对于每个被检查的元素,我们调用一个辅助方法countElementsLessThan,它将返回低于当前元素的元素数。最后,我们将结果存储在result列表中,直到检查remaining列表的每个元素。

然而,我并不完全确定你完全理解你的问题,因为对我来说,你提供的例子应该是:

  

[1; 2; 3; -3; 5; 3]正确的答案是:[0; 1; 2; 0; 4; <强> 3

而不是:

  

[1; 2; 3; -3; 5; 3]正确的答案是:[0; 1; 2; 0; 4; 0]