比较列表 - 检查一个列表是否是第二个列表的一个段

时间:2014-10-23 21:43:39

标签: scala functional-programming comparison-operators

大家早上好(或晚上好:)), 我在检查一个列表是否是第二个列表时遇到问题。第一个列表的所有元素必须是第二个列表的第一个元素。

例如

L1=[1,2,3,4]
L2=[3,4,5,6]
>false

L1=[1,2,3,4]
L2=[1,2,3,4,5,6,7,8]
>true

L1=[-1,-7,3,2]
L2=[1,2,3,4,5]
>false

我知道使用循环然后比较元素会很容易,但我想以功能方式进行。我有想法,但并不聪明,要坚持两个列表(例如使用zip),然后解压缩,设置并比较它是否与第二个列表具有相同的长度,但该方法看起来不太好。 / p>

我是Scala的新人,很抱歉这个愚蠢的问题。我不喜欢代码,但是对于一些建议! :)

谢谢你们!

2 个答案:

答案 0 :(得分:0)

我做了这样的事。现在它起作用了:

  def segment(L1: List[Int], L2: List[Int]) : Boolean = (L1, L2) match {
    case (h1::t1, h2::t2) if (h1 == h2) => segment(t1,t2)
    case(h1::t1, h2::t2) if (h1 != h2) => return false
    case nil => return true;
}

答案 1 :(得分:0)

这是一种惯用的方法;让

val a = (1 to 5).toList    
val b = (2 to 4).toList
val c = List(2,7,4)

然后

a.tails.collectFirst { case l if (l.startsWith(b)) => true }
res: Option[Boolean] = Some(true)

a.tails.collectFirst { case l if (l.startsWith(c)) => true }
res: Option[Boolean] = None

这里tails将在每个子列表上创建一个迭代器,从列表中的项目到列表中的最后一项;只有当我们感兴趣的字符串是任何子列表的 start 时,startsWith才会成功; collectFirst会在Option[Boolean]的第一次成功回复时提供startsWith,否则会提供表示不匹配的None

为了结束这个想法,请考虑这个隐含的类,

implicit class RichList[A](val seg: List[A]) extends AnyVal {
  def isSegmentOf(l: List[A]) = {
    l.tails.collectFirst { case t if (t.startsWith(seg)) => true }
  }
}

因此

b.isSegmentOf(a)
res: Option[Boolean] = Some(true)

c.isSegmentOf(a)
res: Option[Boolean] = None