与Scala中的简单正则表达式匹配的字符串流

时间:2011-12-17 18:00:58

标签: scala stream

这是我上一个问题的后续行动。假设我想要Stream匹配^a+b+$的所有字符串(一个或多个" a"然后一个或多个" b")。

我的编码如下:

def interleave(s1:Stream[String], s2:Stream[String]): Stream[String] =
  if (s1.isEmpty) s2 else Stream.cons(s1.head, interleave(s2, s1.tail))

def generate(s1:Stream[String], s2:Stream[String]): Stream[String] =
  if (s1.isEmpty) s1 else interleave(s2.map(s1.head + _), generate(s1.tail, s2))

def as:Stream[String] = Stream.cons("a", as.map(_ + "a"))

def bs:Stream[String] = Stream.cons("b", bs.map(_ + "b"))

def solve = generate(as, bs)

不幸的是solveout of memory而失败。但是它适用于有限流:例如solve(as take 10, bs take 10)

您如何修复上述代码?您是否希望采用其他方式来解决问题?

2 个答案:

答案 0 :(得分:2)

这个怎么样:

scala> val asbs = for(n <- Stream.from(2);k <- 1 until n) yield "a"*k + "b"*(n-k)
asbs: scala.collection.immutable.Stream[String] = Stream(ab, ?)

scala> asbs.take(10).toList
res0: List[String] = List(ab, abb, aab, abbb, aabb, aaab, abbbb, aabbb, aaabb, aaaab)

scala>

答案 1 :(得分:2)

问题在于,为了能够调用interleave,必须计算generate

def generate(s1:Stream[String], s2:Stream[String]): Stream[String] =
  if (s1.isEmpty) ... else interleave(..., generate(s1.tail, s2))

因此,生成将递归调用自身直到s1.isEmpty,此时它将最终调用所有挂起的interleave。由于s1是无限的,因此永远不会为空。

如果将interleave的第二个参数转换为by-name参数,则递归可以延迟:

def interleave(s1:Stream[String], s2: => Stream[String]): Stream[String] =