【问题标题】:Selection Sort Generic type implementation选择排序泛型类型实现
【发布时间】:2014-04-28 05:38:38
【问题描述】:

我以自己的方式实现了递归版本的选择和快速排序,我正在尝试修改代码,使其可以对任何泛型类型的列表进行排序,我想假设提供的泛型类型可以转换在运行时可比较。

有没有人有链接,代码或教程如何做到这一点? 我正在尝试修改此特定代码

  'def main (args:Array[String]){
    val l = List(2,4,5,6,8)
    print(quickSort(l))
  }
  def quickSort(x:List[Int]):List[Int]={
    x match{
      case xh::xt =>
        {
        val (first,pivot,second) = partition(x)
        quickSort (first):::(pivot :: quickSort(second))
    }
    case Nil => {x}
  }
  }
  def partition (x:List[Int])=
  {
   val pivot =x.head
   var first:List[Int]=List ()
   var second : List[Int]=List ()

   val fun=(i:Int)=> {
     if (i<pivot)
       first=i::first
      else
         second=i::second
   } 
     x.tail.foreach(fun)
     (first,pivot,second)
   }


    enter code here

    def main (args:Array[String]){
    val l = List(2,4,5,6,8)
    print(quickSort(l))
  }
  def quickSort(x:List[Int]):List[Int]={
    x match{
      case xh::xt =>
        {
        val (first,pivot,second) = partition(x)
        quickSort (first):::(pivot :: quickSort(second))
    }
    case Nil => {x}
  }
  }
  def partition (x:List[Int])=
  {
   val pivot =x.head
   var first:List[Int]=List ()
   var second : List[Int]=List ()

   val fun=(i:Int)=> {
     if (i<pivot)
       first=i::first
      else
         second=i::second
   } 
     x.tail.foreach(fun)
     (first,pivot,second)
   } '

语言:斯卡拉

【问题讨论】:

  • “平台:SCALA 语言:JAVA”……所以……它是什么?
  • 抱歉拼写错误,语言是scala,平台是eclipse
  • eclipse和它有什么关系?您的排序算法对执行它的 IDE 是明智的吗?怎么样?

标签: scala


【解决方案1】:

在 Scala 中,Java ComparatorOrdering 取代(非常相似,但带有更多有用的方法)。它们针对多种类型(基元、字符串、bigDecimals 等)实现,您可以提供自己的实现。

然后您可以使用 scala implicit 要求编译器为您选择正确的:

def sort[A]( lst: List[A] )( implicit ord: Ordering[A] ) = {
  ...
}

如果您使用预定义的排序,只需调用:

sort( myLst )

并且编译器将推断出第二个参数。如果要声明自己的排序,请在声明中使用关键字implicit。例如:

implicit val fooOrdering = new Ordering[Foo] {
  def compare( f1: Foo, f2: Foo ) = {...}
}

如果您尝试对 Foo 列表进行排序,它将被隐式使用。

如果同一类型有多个实现,也可以显式传递正确的排序对象:

sort( myFooLst )( fooOrdering )

this post 中的更多信息。

【讨论】:

  • 非常感谢您的 ide,我正在尝试修改此特定的快速排序代码以对任何泛型类型进行排序 [T]
  • @Jide 我发布的快速排序代码已经被修改为对(或可以转换)为 Ordered[A] 的泛型类型 A 进行排序
  • 更正:Comparator 替换为 Ordering,而不是 Comparable
【解决方案2】:

对于快速排序,我将修改“Scala By Example”书中的一个示例,使其更通用。

class Quicksort[A <% Ordered[A]] {
    def sort(a:ArraySeq[A]): ArraySeq[A] =
        if (a.length < 2) a
        else {
            val pivot = a(a.length / 2)
            sort (a filter (pivot >)) ++ (a filter (pivot == )) ++
                sort (a filter(pivot <))
        }
}

用 Int 测试

    scala> val quicksort = new Quicksort[Int]
    quicksort: Quicksort[Int] = Quicksort@38ceb62f

    scala> val a = ArraySeq(5, 3, 2, 2, 1, 1, 9, 39 ,219)
    a: scala.collection.mutable.ArraySeq[Int] = ArraySeq(5, 3, 2, 2, 1, 1, 9, 39, 21
    9)

    scala> quicksort.sort(a).foreach(n=> (print(n), print (" " )))
    1 1 2 2 3 5 9 39 219

使用实现 Ordered 的自定义类进行测试

scala> case class Meh(x: Int, y:Int) extends Ordered[Meh] {
     | def compare(that: Meh) = (x + y).compare(that.x + that.y)
     | }
defined class Meh

scala> val q2 = new Quicksort[Meh]
q2: Quicksort[Meh] = Quicksort@7677ce29

scala> val a3 = ArraySeq(Meh(1,1), Meh(12,1), Meh(0,1), Meh(2,2))
a3: scala.collection.mutable.ArraySeq[Meh] = ArraySeq(Meh(1,1), Meh(12,1), Meh(0
,1), Meh(2,2))

scala> q2.sort(a3)
res7: scala.collection.mutable.ArraySeq[Meh] = ArraySeq(Meh(0,1), Meh(1,1), Meh(
2,2), Meh(12,1))

【讨论】:

    【解决方案3】:

    尽管在编写 Scala 时,我习惯于更喜欢函数式编程风格(通过组合器或递归)而不是命令式编程风格(通过变量和迭代),这一次,对于这个特定问题,老派的命令式嵌套循环会导致为读者提供更简单的代码。对于某些类型的问题(例如通常转换输入缓冲区(如过程)而不是产生新排序的排序算法),我不认为回到命令式风格是错误的

    这是我的解决方案:

    package bitspoke.algo
    
    import scala.math.Ordered
    import scala.collection.mutable.Buffer
    
    abstract class Sorter[T <% Ordered[T]] {
    
      // algorithm provided by subclasses
      def sort(buffer : Buffer[T]) : Unit
    
      // check if the buffer is sorted
      def sorted(buffer : Buffer[T]) = buffer.isEmpty || buffer.view.zip(buffer.tail).forall { t => t._2 > t._1 }
    
      // swap elements in buffer
      def swap(buffer : Buffer[T], i:Int, j:Int) {
        val temp = buffer(i)
        buffer(i) = buffer(j)
        buffer(j) = temp
      }
    }
    
    
    class SelectionSorter[T <% Ordered[T]] extends Sorter[T] {
      def sort(buffer : Buffer[T]) : Unit = {
        for (i <- 0 until buffer.length) {
          var min = i
          for (j <- i until buffer.length) {
            if (buffer(j) < buffer(min))
              min = j
           }
           swap(buffer, i, min)
         }
      }
    }
    

    如您所见,我更喜欢scala.math.Ordered 和Scala View Bounds 而不是Upper Bounds,而不是java.lang.Comparable。这肯定是有效的,这要归功于许多原始类型到丰富包装器的 Scala 隐式转换。

    您可以编写如下客户端程序:

    import bitspoke.algo._
    import scala.collection.mutable._
    
    val sorter = new SelectionSorter[Int]
    val buffer = ArrayBuffer(3, 0, 4, 2, 1)
    sorter.sort(buffer)
    
    assert(sorter.sorted(buffer))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-19
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多