美文网首页Haskell优化算法
K个最大(最小)元素的算法

K个最大(最小)元素的算法

作者: DarkBubble | 来源:发表于2019-03-22 09:36 被阅读0次

    问题描述:给定具有N个元素的全序集合A,比较算符为<=,求最大的K<=N个元素,不要求排序。下面按照取K个最小值的情况讨论。
    基本思想:类似于快速排序法,选择一个元素将其插入到数组的一个位置,使得左侧的元素都小于等于该标记元素,右侧元素都大于等于该元素。

    • 取第一个元素为标记元素,扫描后续的元素,并与其比较,分为三类
      • 一类是全部小于该元素,数组计为A_1,个数计为N_1
      • 一类是全部等于该元素,数组计为A_2,个数计为N_2
      • 一类是全部大于该元素,数组计为A_3,个数计为N_3
      • 定义M_1=N_1, M_2 = N_1+N_2, M_3 = N_1 + N_2 + N_3
    • KM_1,M_2,M_3比较,确定其位置。
    • K=M_1时,返回结果即A_1
    • K=M_2时,返回结果即A_1\cup A_2
    • K=M_3时,返回结果即A集合本身
    • K < M_1时,对A_1集合递归调用上述过程
    • M_1 < K < M_2时,在A_2集合中递归调用上述过程找到A_2集合中的前K-M_1个元素B,返回A_1\cup B
    • M_2 < K < M_3时,在A_3集合中递归调用上述过程,找到A_3集合中的前K-M_2个元素C,返回A_1\cup A_2\cup C

    参考Haskell代码:

    ksplit 0 xs = ([], xs)
    ksplit k xs
        = let x = head xs
              xs1 = filter (<  x) xs
              xs2 = filter (== x) xs
              xs3 = filter (>  x) xs
              n1  = length xs1
              n2  = length xs2 + n1
              n3  = length xs3 + n2
          in  if k > length xs
              then error "not_enough_elements"
              else if k == n1
                   then (xs1, xs2 ++ xs3)
                   else if k == n2
                        then (xs1 ++ xs2, xs3)
                        else if k == n3
                             then (xs, [])
                             else if k < n1
                                  then let (ys1, ys2) = ksplit k xs1
                                       in  (ys1, ys2 ++ xs2 ++ xs3)
                                  else if k < n2 -- k \in (n1, n2)
                                       then (xs1 ++ take (k - n1) xs2, take (n2 - k) xs2 ++ xs3)
                                       else let (ys1, ys2) = ksplit (k - n2) xs3 -- k \in (n2, n3)
                                            in  (xs1 ++ xs2 ++ ys1, ys2)
    
    
    

    相关文章

      网友评论

        本文标题:K个最大(最小)元素的算法

        本文链接:https://www.haomeiwen.com/subject/shnkvqtx.html