我有以下Kotlin功能:
fun func(n: Int): Int {
var count = 1
var m = n
while(m != 1) {
m = if(m.isOdd()) 3 * m + 1 else m / 2
count++
}
return count
}
我想在" functional"中编写这个简单的算法。风格,使用Kotlin的运算符,如map(),count()等。我能想出的最接近的是:
fun func(n: Int): Int {
return n.toList()
.map{ if(it.isOdd()) 3*it+1 else it/2 }
.takeWhile { it != 1 }
.count()
}
显然,上面的代码不起作用,因为map只执行一次,但你知道我想要实现的目标。
PS:toList()只是一个扩展函数,它将int转换为包含该int的列表:
fun Int.toList() = listOf(this)
答案 0 :(得分:7)
由于您不知道将会有多少项,您可以构建一个(可能是无限的)序列,其中每个项目都是根据前一项计算的,然后根据条件it != 1
限制它并计算多少项项目有:
return generateSequence(n) { if (it.isOdd()) 3 * it + 1 else it / 2 }
.takeWhile { it != 1 }
.count()
在这里,generateSequence(n) { ... }
构造一个Sequence<Int>
,其第一个元素为n
,并且每个以下元素都是通过作为lambda传递的代码计算的(它被调用前一个元素,并且仅在查询另一个项目时,即懒惰)。