你的问题太具体了,没有一个通用的函数来解决它,所以我们必须自己编写一个函数。
实现函数式算法的标准策略是分而治之,这基本上意味着提取问题的最小部分,然后在其上逐步构建算法。
执行
好的,显然我们需要做的最小的事情是测试两个项目的连续性:
def testContiguity( a : (Int, Int), b : (Int, Int) ) : Boolean
= a._2 == b._2
然后我们需要一些函数来使用两项比较函数来排列列表。如果标准库有它会很好,但它没有,所以我们定义自己的:
def arrange
[ A ]
( list : List[ A ] )
( f : (A, A) => Boolean )
: List[ List[ A ] ]
= list match {
case a :: b :: tail =>
if( f(a, b) ) putInFirstGroup( a, arrange( b :: tail )( f ) )
else putInNewGroup( a, arrange( b :: tail )( f ) )
case a :: Nil =>
putInNewGroup( a, Nil )
case Nil =>
Nil
}
好的,你可以看到上面的实现依赖于另外两个函数,我们也定义它们:
def putInFirstGroup
[ A ]
( item : A, groups : List[ List[ A ] ] )
: List[ List[ A ] ]
= groups match {
case group :: tail =>
(item :: group) :: tail
case Nil =>
(item :: Nil) :: Nil
}
def putInNewGroup
[ A ]
( item : A, groups : List[ List[ A ] ] )
: List[ List[ A ] ]
= (item :: Nil) :: groups
就是这样!
用法
scala> arrange( List( (1,2), (3,2), (4, 1), (6,2) ) )( testContiguity )
res2: List[List[(Int, Int)]] = List(List((1,2), (3,2)), List((4,1)), List((6,2)))
您现在可以看到我们已经创建了一个非常灵活和通用的解决方案,处理任何类型的项目列表,并允许您使用任何其他测试功能来安排它们。此外,我们还大量利用将复杂算法划分为易于理解的小部分来解决此问题。