Data structures OCaml数据结构,用于查找最后计数的元素

Data structures OCaml数据结构,用于查找最后计数的元素,data-structures,ocaml,Data Structures,Ocaml,我正在寻找回答以下问题的数据结构? 列表中有多少元素低于当前值。我想为列表中的每个元素计算它。此外,它必须是列表的一致子序列 例如: [1;2;3;-3;5;3] 正确答案是: [0; 1; 2; 0; 4; 0] 我不确定我是否完全理解了你的问题,因为你的“正确答案”似乎与你描述问题的方式不一致,但下面是描述问题的可能解决方案: let xs = [1;2;3;-3;5;3] in let comp x y = if (x < y) then -1 else if

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

例如:

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

[0; 1; 2; 0; 4; 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

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

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;;
让rec countelement小于列表值=
匹配列表
| []           -> 0
|头部::尾部->如果头部<值
然后是1+(CountElement小于尾值)
else CountElement小于尾值
;;
(*******************************)
让rec计算剩余的alreadySeen结果=
与剩余的匹配
|[]->结果
|head::tail->let elementsLessThanHead=countElementsLessThan-alreadySeen-head-in
计数尾部(头部::alreadySeen)(结果@[elementslesshanhead])
;;
(*******************************)
让rec打印列表=
匹配列表
|[]->打印新行()
|头::尾->打印头;
打印列表尾部
;;
(*******************************)
让结果=计数[1;2;3;-3;5;3][];;
打印列表结果;;
这里,方法
count
将迭代并将已经看到的元素存储在名为
alreadySeen
的列表中。然后,对于要检查的每个元素,我们调用一个辅助方法
countElementsLessThan
,该方法将返回小于当前元素的元素数。最后,我们将结果存储在
结果
列表中,直到检查
剩余
列表的每个元素

但是,我不能完全确定是否完全理解了您的问题,因为对于我来说,您提供的示例应该是:

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

而不是:

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


不,我们不能对元素进行排序。秩序很重要。我再加一个例子:[1;2;3-5;6;7;10;-1;4]-->[0;1;2;0;1;2;3;0;1]你能更详细地解释一下你是如何得到这个答案的吗?显然,10比数组中的其他元素都大,所以它的值应该大于3,不是吗?即使你按顺序考虑,小于10的值的数量也应该是6,而不是3。是的,在匆忙中我犯了一个错误,我纠正了它:[1;2;3;-5;6;7;10;-1;4]——>[0;1;2;0;4;5;6;0;1],这对我来说仍然不一致,因为如果我理解正确,那么输出应该是[0;1;2;0;4;5;6;1;5]或者我仍然误解了吗?不,现在可以了。为什么最后不能像你建议的那样是5?首先,前一个小于4的数字是-1,但前一个-它是10>4,所以我可以回到一个位置,4仍然是最大值。对于-1。前面的数字是10,所以我不能返回,-1不是最大值。唯一的可能性是0,当我返回0时,-1仍然是最大值问题描述得不清楚。根据上面的描述,我猜想上述问题的解决方案是[1;2;3;0;5;3]。请重试描述所需的算法。
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;;