gpt4 book ai didi

scala - 以 5 的幂递增 scala 中的 for 循环(循环变量)

转载 作者:行者123 更新时间:2023-12-04 09:00:39 24 4
gpt4 key购买 nike

我曾在 Javaranch 上问过这个问题,但无法在那里得到回应。所以也贴在这里:

我有这个特殊要求,其中循环变量的增量是通过在每次迭代后乘以 5 来完成的。在 Java 中,我们可以这样实现:

for(int i=1;i<100;i=i*5){}

在 Scala 中,我正在尝试以下代码-
var j=1
for(i<-1.to(100).by(scala.math.pow(5,j).toInt))
{
println(i+" "+j)
j=j+1
}

但它打印以下输出:
1 1
6 2
11 3
16 4
21 5
26 6
31 7
36 8
....
....

它总是以 5 递增。那么我如何实际将增量乘以 5 而不是添加它。

最佳答案

我们先来解释一下问题。这段代码:

var j=1
for(i<-1.to(100).by(scala.math.pow(5,j).toInt))
{
println(i+" "+j)
j=j+1
}

相当于:
var j = 1
val range: Range = Predef.intWrapper(1).to(100)
val increment: Int = scala.math.pow(5, j).toInt
val byRange: Range = range.by(increment)
byRange.foreach {
println(i+" "+j)
j=j+1
}

所以,当你开始变异时 j , incrementbyRange已经计算过了。和 Range是一个不可变的对象——你不能改变它。即使您在执行 foreach 时产生了新的范围,对象在做 foreach还是一样。

现在,解决方案。简单地说, Range不足以满足您的需求。你想要一个几何级数,而不是一个算术级数。对我来说(似乎几乎所有其他人都在回答),自然的解决方案是使用 StreamIterator创建于 iterate ,它根据前一个值计算下一个值。
for(i <- Iterator.iterate(1)(_ * 5) takeWhile (_ < 100)) {
println(i)
}

编辑:关于流与迭代器
StreamIterator是非常不同的数据结构,它们共享非严格的属性。此属性是启用 iterate 的原因甚至存在,因为这个方法正在创建一个无限的集合1,从中 takeWhile将创建一个有限的 new2 集合。让我们看看这里:
val s1 = Stream.iterate(1)(_ * 5) // s1 is infinite
val s2 = s1.takeWhile(_ < 100) // s2 is finite
val i1 = Iterator.iterate(1)(_ * 5) // i1 is infinite
val i2 = i1.takeWhile(_ < 100) // i2 is finite

这些无限集合是可能的,因为集合不是预先计算的。在 List ,列表中的所有元素实际上在创建列表时存储在某个地方。然而,在上面的例子中,只有每个集合的第一个元素是预先知道的。只有在需要时才会计算所有其他的。

不过,正如我所提到的,这些在其他方面是非常不同的集合。 Streamimmutable数据结构。例如,您可以打印 s2 的内容。任意次数,每次都会显示相同的输出。另一方面, Iterator是可变数据结构。一旦您使用了一个值,该值将永远消失。打印 i2的内容两次,第二次它将是空的:
scala> s2 foreach println
1
5
25

scala> s2 foreach println
1
5
25

scala> i2 foreach println
1
5
25

scala> i2 foreach println

scala>
Stream另一方面,是 lazy收藏。一旦计算出一个值,它将保持计算状态,而不是每次都被丢弃或重新计算。请参阅下面该行为的一个示例:
scala>     val s2 = s1.takeWhile(_ < 100)    // s2 is finite
s2: scala.collection.immutable.Stream[Int] = Stream(1, ?)

scala> println(s2)
Stream(1, ?)

scala> s2 foreach println
1
5
25

scala> println(s2)
Stream(1, 5, 25)

所以 Stream如果不小心,实际上可以填满内存,而 Iterator占据恒定空间。另一方面, Iterator 会让人感到惊讶。 ,因为它的副作用。

(1) 事实上, Iterator根本不是一个集合,即使它共享集合提供的许多方法。另一方面,从您给出的问题描述来看,您对拥有一组数字并不真正感兴趣,只是对它们进行迭代。

(2) 其实,虽然 takeWhile将创建一个新的 Iterator在 Scala 2.8.0 上,这个新的迭代器仍然会链接到旧的迭代器,一个的变化会对另一个产生副作用。这有待讨论,他们将来可能会真正独立。

关于scala - 以 5 的幂递增 scala 中的 for 循环(循环变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4194075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com