F # Effectively remove n items from the end of a set

I know that I can remove the last item from the set:

s.Remove(s.MaximumElement)

But if I want to remove n maximum elements ... Am I just doing the above n times, or is there a faster way to do this?

To be clear, this is an obvious solution:

let rec removeLastN (s : Set<'a>, num : int) : Set<'a> = 
    match num with
    | 0 -> s
    | _ -> removeLast(s.Remove(s.MinimumElement), num-1)

But this is due to the creation of a new set n times. Is there a way to do this and only create a new set once?

+5
source share
3 answers

But this is due to the creation of a new set n times. Is there a way to do this and only create a new set once?

, . , , O (lg n) - :) O (lg n) min , , .

, , , , . , AVL RB , , .

treap , , , . AVL RB, treap node, , . , :

http://pastebin.com/j0aV3DJQ

split, , , , . split O (lg n), , - , , .

n ... n , ?

Treap:

open Treap

let nthLargest n t = Seq.nth n (Treap.toSeqBack t)
let removeTopN n t =
    let largest = nthLargest n t
    let smallerValues, wasFound, largerValues = t.Split(largest)
    smallerValues

let e = Treap.empty(fun (x : int) (y : int) -> x.CompareTo(y))
let t = [1 .. 100] |> Seq.fold (fun (acc : Treap<_>) x -> acc.Insert(x)) e
let t' = removeTopN 10 t

removeTopN O (n + lg m) , n - , m - .

, ;)

+1

. OCaml split, Set, , Set, . Set.difference Set.

0

F # Set.partition Set.filter :

let s = Set([1;4;6;9;100;77])

let a, b = Set.partition (fun x -> x <= 10) s

let smallThan10 = Set.filter (fun x -> x < 10) s

, , i- , :

let nth (n:int) (s:'a Set) = 
    s |> Set.toSeq |> Seq.nth n

remove-top-n:

let removeTopN n (s:'a Set) = 
    let size = s.Count
    let m = size - n
    let mvalue = nth m s
    Set.filter (fun x -> x < mvalue) s

and test it:

removeTopN 3 s

and get:

val it : Set<int> = set [1; 4; 6]

Note that removeTopN does not work for a set containing several identical values.

0
source

All Articles