我如何打破一个循环?
var largest=0
for(i<-999 to 1 by -1) {
for (j<-i to 1 by -1) {
val product=i*j
if (largest>product)
// I want to break out here
else
if(product.toString.equals(product.toString.reverse))
largest=largest max product
}
}
如何将嵌套for循环转换为尾递归?
来自FOSDEM 2009 Scala Talk http://www.slideshare.net/Odersky/fosdem-2009-1013261
第22页:
中断并继续
Scala没有它们。为什么?
它们有点迫不得已;最好使用许多较小的函数
发布如何与闭包交互。
他们是不需要的!
怎么解释呢?
我是Scala的新手,但是这样可以避免抛出异常和重复方法:
object awhile {
def apply(condition: () => Boolean, action: () => breakwhen): Unit = {
while (condition()) {
action() match {
case breakwhen(true) => return ;
case _ => { };
}
}
}
case class breakwhen(break:Boolean);
像这样使用它:
var i = 0
awhile(() => i < 20, () => {
i = i + 1
breakwhen(i == 5)
});
println(i)
如果你不想断:
awhile(() => i < 20, () => {
i = i + 1
breakwhen(false)
});
我不知道Scala风格在过去的9年里发生了多大的变化,但我发现一个有趣的现象:大多数现有的答案都使用了var,或者是难以阅读的递归。尽早退出的关键是使用惰性集合生成可能的候选对象,然后分别检查条件。生成产物:
val products = for {
i <- (999 to 1 by -1).view
j <- (i to 1 by -1).view
} yield (i*j)
然后在不生成所有组合的情况下从视图中找到第一个回文:
val palindromes = products filter {p => p.toString == p.toString.reverse}
palindromes.head
要找到最大的回文(尽管懒惰不会给你带来什么好处,因为你必须检查整个列表):
palindromes.max
您的原始代码实际上是在检查第一个大于后续产品的回文,这与检查第一个回文是一样的,只是在一个奇怪的边界条件下,我认为这不是您想要的。乘积不是严格单调递减的。例如,998*998大于999*997,但在循环中出现得更晚。
不管怎样,分离的惰性生成和条件检查的优点是,你写它的时候就像使用整个列表一样,但它只生成你需要的东西。你可以说是两全其美了。