kotlin - 在 Kotlin 中以 O(n) 时间以纯函数式编程风格计算所有前缀和
问题描述
是否可以在 Kotlin 的 O(n) 时间内以纯函数式编程风格计算数组的所有前缀和?
我所说的纯函数式编程的意思是允许仅对集合使用函数式编程扩展函数,例如_Collections,ktmap
中的,reduce
, fold
,sum
等,而传统的命令式编程方法涉及更改状态和可变数据,例如普通循环,又名可变变量s,并且不允许使用可变数组。(我认为这符合维基百科上的定义)var
更具体地说,这里是我想要实现的一个例子,它是用在 O(n) 时间内运行的命令式编程编写的,另一个是在 O(n^2) 时间内运行的函数式编程。
fun prefixSumsImperative(numbers: IntArray): IntArray {
val prefixSums = IntArray(numbers.size)
var prefixSum = 0
for ((i, number) in numbers.withIndex()) {
prefixSum += number
prefixSums[i] = prefixSum
}
return prefixSums
}
fun prefixSumsFunctionalONSquared(numbers: IntArray): IntArray =
(0 until numbers.size).map { numbers.take(it).sum() }.toIntArray()
解决方案
从 Kotlin 1.4 开始,您可以为此目的使用scan
和函数:runningFold
fun prefixSumsFunctional(numbers: IntArray): IntArray =
numbers.runningFold(0) { sum, num ->
sum + num
}.toIntArray()
推荐阅读
- typescript - 获取所有值表示标志枚举中的十进制值
- c++ - 可能 boost::asio::ip::udp::socket::send_to 甚至会失败?
- multithreading - 启动由信号量管理的多个线程
- python - 如何在 Selenium Python 中使用 WebDriverWait 触发可点击元素后从弹出窗口中检索数据?
- javascript - 将项目从函数推送到数组中
- c++ - 带有模板作为返回类型的 Trompeloeil MAKE_MOCK0
- javascript - 使用 Chrome,window.open() 操作取决于 shift 键
- scala - 如何在akka http的路由标头中对OAuth2BearerToken进行单元测试
- javascript - .data() 处的 D3 新数据使 svg 重绘而不是更新节点位置
- javascript - toFixed(2) 函数中的 Javascript 错误?