【问题标题】:Scala: How to sort an array within a specified range of indices?Scala:如何在指定的索引范围内对数组进行排序?
【发布时间】:2013-07-08 06:58:46
【问题描述】:

我已经在代码中有一个比较函数“compr”来比较两个值。

我想要这样的东西:

Sorting.stableSort(arr[i,j] , compr)

其中 arr[i,j] 是数组中元素的范围。

【问题讨论】:

    标签: scala sorting stable-sort


    【解决方案1】:

    将切片作为视图,排序并复制回来(或将切片作为工作缓冲区)。

    scala> val vs = Array(3,2,8,5,4,9,1,10,6,7)
    vs: Array[Int] = Array(3, 2, 8, 5, 4, 9, 1, 10, 6, 7)
    
    scala> vs.view(2,5).toSeq.sorted.copyToArray(vs,2)
    
    scala> vs
    res31: Array[Int] = Array(3, 2, 4, 5, 8, 9, 1, 10, 6, 7)
    

    在 REPL 之外,不需要额外的 .toSeq

    vs.view(2,5).sorted.copyToArray(vs,2)
    

    【讨论】:

    • 如果我使用对象而不是原语,那么我必须扩展 Ordering[T] 类并重载比较函数。对吗?
    • 或使用sortWith(comparator)。请注意,元组已经有排序,请参阅 math.Ordering。还有Ordering.by.
    【解决方案2】:

    将数组拆分成三部分,中间部分排序然后concat,不是最有效的方式,但这是关心性能的FP =)

    val sorted = 
      for {
        first       <- l.take(FROM)
        sortingPart <- l.slice(FROM, UNTIL)
        lastPart    <- l.takeRight(UNTIL)
      } yield (first ++ Sorter.sort(sortingPart) ++ lastPart)
    

    【讨论】:

      【解决方案3】:

      类似的东西:

      def stableSort[T](x: Seq[T], i: Int, j: Int, comp: (T,T) => Boolean ):Seq[T] = {
          x.take(i) ++ x.slice(i,j).sortWith(comp) ++ x.drop(i+j-1)
      }                                         
      
      def comp: (Int,Int) => Boolean = { case (x1,x2) => x1 < x2 } 
      val x = Array(1,9,5,6,3)                           
      stableSort(x,1,4, comp)
      // > res0: Seq[Int] = ArrayBuffer(1, 5, 6, 9, 3)
      

      如果你的类实现了 Ordering,它会不那么麻烦。

      【讨论】:

        【解决方案4】:

        在不重新实现排序的情况下,这应该尽可能好。仅创建一个具有要排序的切片大小的额外数组。

        def stableSort[K:reflect.ClassTag](xs:Array[K], from:Int, to:Int, comp:(K,K) => Boolean) : Unit = {
          val tmp = xs.slice(from,to)
          scala.util.Sorting.stableSort(tmp, comp)
          tmp.copyToArray(xs, from)
        }
        

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 2011-11-06
          • 2023-01-21
          • 2017-07-16
          • 2018-02-04
          • 2019-10-11
          • 2021-12-10
          • 1970-01-01
          • 2010-11-11
          相关资源
          最近更新 更多