如何检查给定的List [Int]是否按scala排序?

时间:2015-10-25 11:03:07

标签: scala

我想知道scala中是否存在isSorted()函数。

问题:检查List[Int]是否已排序,如果不是删除最小的数字并再次执行,直到List[Int]排序?

我只想要1或2行程序。

13 个答案:

答案 0 :(得分:13)

您可以比较包含多于1个项目的列表的输入序列中的每一对:

def isSorted[T](s: Seq[T])(implicit ord: Ordering[T]): Boolean = s match {
    case Seq() => true
    case Seq(_) => true
    case _ => s.sliding(2).forall { case Seq(x, y) => ord.lteq(x, y) }
}

答案 1 :(得分:10)

这不是最佳解决方案,但您可以在列表中使用sorted方法,然后将其与原始方法进行比较;

def sorted(l: List[Int]): Boolean = l == l.sorted

答案 2 :(得分:5)

有些懒惰:

def isSorted(l:List[Int]):Boolean = {
   val list = l.view
   !list.zip(list.tail).exists {case (x,y) => x>y}
}

答案 3 :(得分:2)

执行排序只是为了检查列表是否已经排序有点过分。这里的最佳解决方案似乎是最明显的解决方案,它只是用人类语言描述问题并将其转换为代码:

def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list match {
    case Nil => true // an empty list is sorted
    case x :: Nil => true // a single-element list is sorted
    case x :: xs => ord.lteq(x, xs.head) && isSorted(xs) // if the first two elements are ordered and the rest are sorted, the full list is sorted too
}

如果你想缩短它,你可以交换第二种情况以获得一点可读性:

def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list match {
    case Nil => true
    case x :: xs => xs.headOption.fold(true)(ord.lteq(x, _)) && isSorted(xs)
}

如果你想要一个单行,那根本就不可读:

def isSorted[T](list: List[T])(implicit ord: Ordering[T]): Boolean = list.headOption.fold(true)(a => list.tail.headOption.fold(true)(ord.lteq(a, _) && isSorted(list.tail.tail)))

答案 4 :(得分:1)

低效但易于理解的答案:

#include <string>

答案 5 :(得分:1)

l == l.sorted没有为我工作,设法用l sameElements l.sorted

答案 6 :(得分:0)

这是您的单行作业解决方案

def removeMinWhileNotSorted[A: Ordering](xs: List[A]): List[A] =  if (xs == xs.sorted) xs else xs.splitAt(xs.indexOf(xs.min))  match {case (prefix, m :: postfix) => removeMinWhileNotSorted(prefix ++ postfix)}

答案 7 :(得分:0)

它不存在。但这很容易做到:使用列表的连接版本创建一个列表,并根据需要对相同的列表进行排序,并验证连接列表的两个元素是否相同。

这样的事情:

import org.junit.Assert._

val sortedList = List(1, 3, 5, 7)
val unsortedList = List(10, 1, 8, 3, 5, 5, 2, 9)

// detailed test. It passes.
sortedList
  .zip(sortedList.sortWith((a,b) => a.compareTo(b) < 0)) // this is the required sorting criteria.
  .foreach(x => assertEquals("collection is not sorted", x._1, x._2))

// easier to read but similar test. It fails.
unsortedList
  .zip(unsortedList.sorted) // this is the required sorting criteria.
  .foreach(x => assertEquals("collection is not sorted", x._1, x._2))

一个功能可能是:

def isSorted(list: List[Int]): Boolean = !list.zip(list.sortWith((a, b) => a.compareTo(b) < 0)).exists(p => !p._1.equals(p._2))

答案 8 :(得分:0)

def isSorted[T <% Ordered[T]](list: List[T]): Boolean =
    list.sliding(2).forall(p =>  (p.size==1) || p(0) < p(1))

答案 9 :(得分:0)

我认为如果两个相邻元素相等,那么它也是合法的。

 def isSorted[T <% Ordered[T]](l: List[T]):Boolean ={
   val a = l.toArray
   (1 until a.length).forall(i => a(i-1) <= a(i))
 }

答案 10 :(得分:0)

另一种可能性(不一定比其他一些建议要好)

def isSorted[T <% Ordered[T]](a: List[T]): Boolean =
    if (a == Nil) true // an empty list is sorted
    else a.foldLeft((true, a.head))(
        (prev, v1) => {
            val (p, v0) = prev
        (p && v0 <= v1, v1)
    })._1

一些测试用例的结果:

isSorted(Nil) -> true 
isSorted(1 :: Nil) -> true
isSorted(2 :: 3 :: Nil) -> true
isSorted(1 :: 2 :: 5 :: 8 :: Nil) -> true
isSorted(1 :: 1 :: 2 :: 2 :: Nil) -> true
isSorted(3 :: 2 :: Nil) -> false
isSorted(1 :: 2 :: 3 :: 1 :: Nil) -> false

答案 11 :(得分:0)

def isSorted(xs:List [Int]):布尔值=(xs.tail zip xs).forall(pair => pair._1-pair._2> 0)

答案 12 :(得分:0)

您可以使用尾部递归来减少创建对象的次数,并避免长列表的堆栈溢出。此版本是惰性的,函数在第一个无序对之后立即返回值。

class TestA(unittest.TestCase):

   @mock.patch("path.to.A.Operation")
   def test_create_assertion_processor(self, mock_operation):
      message = {}
      mock_operation_instance = mock.MagicMock()  # missing bracket here.
      mock_operation.return_value = mock.MagicMock(return_value = mock_operation_instance)

      A().process(message)

      mock_operation.assert_called_once_with(message)
      mock_operation_instance.execute.assert_called()